Package com.sun.ejb.codegen

Source Code of com.sun.ejb.codegen.JavaCompiler

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/

/*
* JavaCompiler.java
*
* Created on June 22, 2002, 8:56 PM
*
* @author  bnevins
* @version $Revision: 1.4 $
* <BR> <I>$Source: /cvs/glassfish/appserv-core/src/java/com/sun/ejb/codegen/JavaCompiler.java,v $
*
*/

package com.sun.ejb.codegen;

import java.io.*;
import java.util.*;
import java.util.logging.*;
import com.sun.enterprise.util.OS;
import com.sun.enterprise.util.StringUtils;
import com.sun.enterprise.util.i18n.StringManager;
import com.sun.enterprise.util.io.FileUtils;
import com.sun.enterprise.server.Constants;
import com.sun.tools.javac.Main;

class JavaCompiler extends Compiler
{
    private static final String JAVAC_EXT_DIRS_OPTION = "-extdirs";
    private static final String JAVAC_OUT_OF_PROCESS =
                                "com.sun.aas.deployment.javacoutofprocess";


  JavaCompiler(List theOptions, List theFiles) throws JavaCompilerException
  {
    super(theOptions, theFiles);
  }

  ///////////////////////////////////////////////////////////////////////////

  protected void internal_compile() throws JavaCompilerException, ProcessExecutorException
  {
    // 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();
  }
 
  ///////////////////////////////////////////////////////////////////////////

  private boolean userCompile() throws ProcessExecutorException
  {
    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;
  }
 
  //////////////////////////////////////////////////////////////////////////

  private boolean fastjavacCompile() throws ProcessExecutorException
  {
    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 boolean javacCompile() throws JavaCompilerException,
                                              ProcessExecutorException
  {
    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;
  }
 
  ///////////////////////////////////////////////////////////////////////////

  protected void internal_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 void initUserCompiler()
  {
    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());
    }
  }
 
 
  ///////////////////////////////////////////////////////////////////////////

  private void initFastjavac()
  {
    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 void initJavac()
  {
    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;
  }

  /**
   * 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.
   *
   * <p>For flexibility, a environmental variable is checked first.  Failing that,
   * it will use the hard-coded default value.
   *
    * <p>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
   */ 
  private static int getFastjavacTimeout()
  {
    if (fastJavacTimeout < 0 )
    {
      fastJavacTimeout = getTimeout(Constants.FASTJAVAC_TIMEOUT_MS, Constants.DEFAULT_FASTJAVAC_TIMEOUT_MS, 1000, 300000);
    }
    return fastJavacTimeout;
  }

  /** 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.
   *
   * <p>For flexibility, a environmental variable is checked first.  Failing that,
   * it will use the hard-coded default value.
   *
    * <p>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
   */ 
  private static int getJavacTimeout()
  {
    if (javacTimeout < 0 )
    {
      javacTimeout = getTimeout(Constants.JAVAC_TIMEOUT_MS, Constants.DEFAULT_JAVAC_TIMEOUT_MS, 1000, 900000);
    }
    return javacTimeout;
  }

  /** 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.
   *
   * <p>For flexibility, a environmental variable is checked first.  Failing that,
   * it will use the hard-coded default value.
   *
    * <p>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
   */ 
  private static int getUserSpecifiedCompilerTimeout()
  {
    if (userTimeout < 0 )
    {
      userTimeout = getTimeout(Constants.USER_SPECIFIED_COMPILER_TIMEOUT_MS, Constants.DEFAULT_USER_SPECIFIED_COMPILER_TIMEOUT_MS, 1000, 900000);
    }
    return userTimeout;
  }
 
  ///////////////////////////////////////////////////////////////////////////

  private          File      userExe;
  private          File      fastExe;
  private          File      javacExe;
  private          List      userOptions;

  // used for caching timeouts to prevent memory leaks. must be initialized to -1.
  private  static        int      fastJavacTimeout = -1;
  private  static        int      javacTimeout = -1;
  private  static        int      userTimeout = -1;

  ///////////////////////////////////////////////////////////////////////////
/* testing code...
  public static void main(String[] args)
  {
    System.out.println("Test 1: install-root == C:/ias7 and JAVA_HOME not set");
    System.setProperty(Constants.INSTALL_ROOT, "C:/ias7");
    test();
    System.out.println("Test 2: install-root == C:/ias7 and JAVA_HOME == c:/jdk1.4");
    System.setProperty("JAVA_HOME", "C:/jdk1.4");
    test();
  }   
 
 
  ///////////////////////////////////////////////////////////////////////////

  public static void test()
  {
    List opt = new ArrayList();
    List f   = new ArrayList();
 
    opt.add("-d");
    opt.add("c:/tmp/crap");
    opt.add("-g");
    f.add("c:/src/java/junk/Crap.java");
 
    try
    {
      JavaCompiler jc = new JavaCompiler(opt, f);
      logger.log(Level.SEVERE, "fastExe: " + ((jc.fastExe == null)    ? "null" : jc.fastExe.getPath()) );
      logger.log(Level.SEVERE, "javacExe: " + ((jc.javacExe == null)  ? "null" : jc.javacExe.getPath()) );
      logger.log(Level.SEVERE, "jdkDir: " + ((jc.jdkDir == null)    ? "null" : jc.jdkDir.getPath()) );
      jc.compile();
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
  }
**/
}
 
TOP

Related Classes of com.sun.ejb.codegen.JavaCompiler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.