FileDocCategorySizeDatePackage
JavaCompiler.javaAPI DocGlassfish v2 API14344Fri May 04 22:32:58 BST 2007com.sun.ejb.codegen

JavaCompiler

public class JavaCompiler extends Compiler

Fields Summary
private static final String
JAVAC_EXT_DIRS_OPTION
private static final String
JAVAC_OUT_OF_PROCESS
private File
userExe
private File
fastExe
private File
javacExe
private List
userOptions
private static int
fastJavacTimeout
private static int
javacTimeout
private static int
userTimeout
Constructors Summary
JavaCompiler(List theOptions, List theFiles)



	     
	
		super(theOptions, theFiles);
	
Methods Summary
private booleanfastjavacCompile()

		if(fastExe == null || jdkDir == null)
			return false;

		ArrayList cmd = new ArrayList();
		cmd.add(fastExe.getPath());
		cmd.add("-jdk");
		cmd.add(jdkDir.getPath());
		cmd.addAll(options);
		addJavaFiles(cmd);
		String[] cmds = new String[cmd.size()];
		cmds = (String[])cmd.toArray(cmds);
		runProcess(cmds, getFastjavacTimeout() * files.size());
		logCompilerName("fastjavac");
		return true;
	
private static intgetFastjavacTimeout()
Returns the timeout, in milliseconds, for each java file. The compiler calling code will multiply this value by the number of java files. If the compiler takes longer than this amount of time the process will be killed. This is to avoid hangs.

For flexibility, a environmental variable is checked first. Failing that, it will use the hard-coded default value.

This method caches the value of timeout in "fastJavacTimeout" variable to prevent memory leak seen in the System.getProperty method in Compiler.java

return
The timeout, in milliseconds, for each java file

		if (fastJavacTimeout < 0 ) 
		{
			fastJavacTimeout = getTimeout(Constants.FASTJAVAC_TIMEOUT_MS, Constants.DEFAULT_FASTJAVAC_TIMEOUT_MS, 1000, 300000);
		}
		return fastJavacTimeout;
	
private static intgetJavacTimeout()
Returns the timeout, in milliseconds, for each java file. The compiler calling code will multiply this value by the number of java files. If the compiler takes longer than this amount of time the process will be killed. This is to avoid hangs.

For flexibility, a environmental variable is checked first. Failing that, it will use the hard-coded default value.

This method caches the value of timeout in "javacTimeout" variable to prevent memory leak seen in the System.getProperty method in Compiler.java

return
The timeout, in milliseconds, for each java file

		if (javacTimeout < 0 ) 
		{
			javacTimeout = getTimeout(Constants.JAVAC_TIMEOUT_MS, Constants.DEFAULT_JAVAC_TIMEOUT_MS, 1000, 900000);
		}
		return javacTimeout;
	
private static intgetUserSpecifiedCompilerTimeout()
Returns the timeout, in milliseconds, for each java file. The compiler calling code will multiply this value by the number of java files. If the compiler takes longer than this amount of time the process will be killed. This is to avoid hangs.

For flexibility, a environmental variable is checked first. Failing that, it will use the hard-coded default value.

This method caches the value of timeout in "userTimeout" variable to prevent memory leak seen in the System.getProperty method in Compiler.java

return
The timeout, in milliseconds, for each java file

		if (userTimeout < 0 ) 
		{
			userTimeout = getTimeout(Constants.USER_SPECIFIED_COMPILER_TIMEOUT_MS, Constants.DEFAULT_USER_SPECIFIED_COMPILER_TIMEOUT_MS, 1000, 900000);
		}
		return userTimeout;
	
private voidinitFastjavac()

		if(installRoot == null || jdkDir == null)
			return;
		
		String fastName;
		/*
		// WBN -- Allow config of fastjavac in the environment
		String fastName = System.getProperty(Constants.FASTJAVAC_COMPILER);
		
		if(StringUtils.ok(fastName))
		{
			fastExe = new File(fastName); 

			if(fastExe.exists())
			{
				fastExe = FileUtils.safeGetCanonicalFile(fastExe);
				return;
			}
			fastExe = null;
		}
		*/
		
		if(OS.isWindows())
			fastName	= "fastjavac.exe";
		else if(OS.isSun())
			fastName	= "fastjavac.sun";
		else if(OS.isLinux())
			fastName	= "fastjavac.linux";
		else
			fastName	= null;
		
		if(fastName == null)
			return;

		// if fastjavac app exists -- set it
		fastExe = new File(installRoot + "/studio4/bin/fastjavac/" + fastName); //now named studio4

		if(fastExe.exists())
			fastExe = FileUtils.safeGetCanonicalFile(fastExe);
		else
			fastExe = null;
	
private voidinitJavac()

		if(jdkDir == null)
			return;
		
		String javacName;
		
		if(OS.isWindows())
		{
			javacName	= "javac.exe";
		}
		else
		{
			javacName	= "javac";
		}

		javacExe = new File(jdkDir, "/bin/" + javacName);

		if(javacExe.exists())
			javacExe = FileUtils.safeGetCanonicalFile(javacExe);
		else
			javacExe = null;
	
private voidinitUserCompiler()

		String userSpecified = getSystemPropertyIgnoreCase(Constants.USER_SPECIFIED_COMPILER);
		
		if(!StringUtils.ok(userSpecified))
			return;
		
		userExe = new File(userSpecified);

		if(!userExe.exists())
		{
			String msg = localStrings.getStringWithDefault(
				"java_compiler.bad_user_compiler", 
				"Can't locate user-specified Java Compiler for deployment.  " 
					+"Environmental Variable= {0}, Value = {1}",
				new Object[] { Constants.USER_SPECIFIED_COMPILER, userSpecified } );

			logger.warning(msg);
			userExe = null;
			return;
		}
		
		// note: it is difficult to handle spaces inside options.
		// at least without requiring the user to specify the args as:
		// xxx1, xxx2, xxx3, etc.  That's too painful for them.  Or I could
		// parse out quote-delimited Strings.  Maybe later.  What
		// are the chances that they will use spaces in filenames anyways?

		userExe = FileUtils.safeGetCanonicalFile(userExe);
		String opts = getSystemPropertyIgnoreCase(Constants.USER_SPECIFIED_COMPILER_OPTIONS);
		
		if(!StringUtils.ok(opts))
			return;
		
		StringTokenizer tok = new StringTokenizer(opts);
		
		while(tok.hasMoreTokens())
		{
			userOptions.add(tok.nextToken());
		}
	
protected voidinternal_compile()

		// note: we are NOT catching Exceptions and then trying the next one.
		// An Exception means there was a compile error and it would be a waste of
		// time to run another compile.
		// if they return true -- it means the facility exists AND everything compiled OK
		// note: only allow JavaCompilerException out of here -- catch everything else
		// and wrap it!!
		
		if(userCompile()) {
			return;
                }

		if(fastjavacCompile()) {
			return;
                }

		javacCompile();
	
protected voidinternal_init()

		fastExe		= null;
		javacExe	= null;
		userExe		= null;
		userOptions	= new ArrayList();		
		
		initUserCompiler();
		initFastjavac();
		initJavac();
		logger.log(Level.FINE, "fastExe: " + ((fastExe == null)		? "null" : fastExe.getPath()) );
		logger.log(Level.FINE, "javacExe: " + ((javacExe == null)	? "null" : javacExe.getPath()) );
		logger.log(Level.FINE, "jdkDir: " + ((jdkDir == null)		? "null" : jdkDir.getPath()) );
	
private booleanjavacCompile()

		if(javacExe == null)
			return false;
		
                boolean outOfProcess = 
                    Boolean.getBoolean(JAVAC_OUT_OF_PROCESS);

		ArrayList cmd = new ArrayList();
                if (outOfProcess) {
                    cmd.add(javacExe.getPath());
                }
                cmd.add(JAVAC_EXT_DIRS_OPTION);
                cmd.add(System.getProperty(JAVA_EXT_DIRS_SYS_PROP));
    	        cmd.addAll(options);
	        addJavaFiles(cmd);
	        String[] cmds = new String[cmd.size()];
	        cmds = (String[])cmd.toArray(cmds);

                if (outOfProcess) {
                    runProcess(cmds, getJavacTimeout() * files.size());
                } else {
                    try {
                        ByteArrayOutputStream bos = 
                            new ByteArrayOutputStream();
                        PrintWriter pw = new PrintWriter(bos); 
                        Main compiler = new Main();
                        int ret = compiler.compile(cmds, pw);
                        if (ret != 0) {
                            byte[] errorBytes = bos.toByteArray();
                            String errorString = new String(errorBytes); 
                            throw new JavaCompilerException(
                                "java_compiler.error", "Native compiler returned an error: {0}\nError messages are: {1}", new Object[] { new Integer (ret), errorString } );
                        }
                    }
                    catch(JavaCompilerException jce) {
                        throw jce;
                    }
                    catch(Throwable t)
                    {
                        throw new JavaCompilerException(
                            "java_compiler.unknown_exception",
                            "JavaC compiler threw an Exception", t);
                    }
                }
		logCompilerName("javac");
		return true;
	
private booleanuserCompile()

		if(userExe == null)
			return false;
		
		ArrayList cmd = new ArrayList();
		cmd.add(userExe.getPath());
                cmd.add(JAVAC_EXT_DIRS_OPTION);
                cmd.add(System.getProperty(JAVA_EXT_DIRS_SYS_PROP));
		cmd.addAll(userOptions);
		cmd.addAll(options);
		cmd.addAll(files);
		
		String[] cmds = new String[cmd.size()];
		cmds = (String[])cmd.toArray(cmds);
		runProcess(cmds, getUserSpecifiedCompilerTimeout() * files.size());
		logCompilerName(userExe.getName());
		return true;