001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: CompilationUtils.java 3634 2007-01-08 21:42:24Z gbevin $
007: */
008: package com.uwyn.rife.tools;
009:
010: import com.uwyn.rife.config.RifeConfig;
011: import com.uwyn.rife.tools.exceptions.CompilationFailedException;
012: import com.uwyn.rife.tools.exceptions.FileUtilsErrorException;
013: import java.io.ByteArrayOutputStream;
014: import java.io.File;
015: import java.io.IOException;
016: import java.io.PrintWriter;
017: import java.lang.reflect.InvocationTargetException;
018: import java.lang.reflect.Method;
019: import java.util.ArrayList;
020: import java.util.List;
021:
022: public abstract class CompilationUtils {
023: public static File compile(String filenameJava, File fileClass,
024: String generationPath, String classpath)
025: throws CompilationFailedException {
026: try {
027: // compile the java source file to a class file
028: if ((!RifeConfig.Global.isJavaCompilerPathSet() || RifeConfig.Global
029: .getJavaCompilerInternal())
030: && RifeConfig.Global
031: .isInternalJavaCompilerAvailable()) {
032: String[] args = new String[] { "-g", "-classpath",
033: classpath, "-d", generationPath, filenameJava };
034: Method compile_method = null;
035: ByteArrayOutputStream errors_outputstream = new ByteArrayOutputStream();
036: PrintWriter errors_printwriter = new PrintWriter(
037: errors_outputstream);
038:
039: // try to compile with printwriter support for error handling
040: // otherwise use the regular compile method
041: // this is needed for ibm jdk support
042: try {
043: compile_method = com.sun.tools.javac.Main.class
044: .getDeclaredMethod("compile", new Class[] {
045: String[].class, PrintWriter.class });
046: } catch (Throwable e) {
047: compile_method = null;
048: }
049:
050: // use the compile method with error reporting if it exists
051: if (compile_method != null) {
052: try {
053: Object status = compile_method
054: .invoke(null, new Object[] { args,
055: errors_printwriter });
056: if (Integer.parseInt(String.valueOf(status)) != 0) {
057: throw new CompilationFailedException(
058: filenameJava, errors_outputstream
059: .toString(), null);
060: }
061: } catch (IllegalAccessException e) {
062: compile_method = null;
063: } catch (InvocationTargetException e) {
064: compile_method = null;
065: } catch (IllegalArgumentException e) {
066: compile_method = null;
067: }
068: }
069:
070: // use the regular compile method
071: if (null == compile_method) {
072: int status = com.sun.tools.javac.Main.compile(args);
073: if (status != 0) {
074: throw new CompilationFailedException(
075: filenameJava, "<unknown error>", null);
076: }
077: }
078: } else {
079: // setup the command
080: List<String> command_elements = new ArrayList<String>();
081: command_elements.add(RifeConfig.Global
082: .getJavaCompilerPath());
083: if (RifeConfig.Global.areJavaCompilerArgsSet()) {
084: command_elements.addAll(RifeConfig.Global
085: .getJavaCompilerArgs());
086: }
087: command_elements.add("-g");
088: command_elements.add("-d");
089: command_elements.add(generationPath);
090: command_elements.add(filenameJava);
091:
092: String[] commands = new String[command_elements.size()];
093: command_elements.toArray(commands);
094:
095: // execute the command
096: Process javac = ExecUtils.exec(commands,
097: new String[] { "CLASSPATH=" + classpath });
098:
099: if (javac.exitValue() != 0 || !fileClass.exists()) {
100: String error_message = null;
101: try {
102: error_message = FileUtils.readString(javac
103: .getErrorStream());
104: } catch (FileUtilsErrorException e) {
105: error_message = "<unknown error>";
106: }
107:
108: if (fileClass.exists()) {
109: fileClass.delete();
110: }
111: throw new CompilationFailedException(filenameJava,
112: error_message, null);
113: }
114: }
115: } catch (IOException e) {
116: if (fileClass.exists()) {
117: fileClass.delete();
118: }
119: throw new CompilationFailedException(
120: filenameJava,
121: "An error occurred while launching the Java compiler.\n\nThere can be several reasons for this:\n- the JDK is maybe not installed; or\n- the compiler can't be found through your operating system's PATH environment variable; or\n- your operating system can't find the compiler path '"
122: + RifeConfig.Global.getJavaCompilerPath()
123: + "', try setting it up through the JAVA_COMPILER_PATH configuration parameter; or\n- the tools.jar file from the JDK isn't present in the classpath of your execution environment (servlet container).",
124: e);
125: } catch (InterruptedException e) {
126: if (fileClass.exists()) {
127: fileClass.delete();
128: }
129: throw new CompilationFailedException(filenameJava, null, e);
130: }
131:
132: return fileClass;
133: }
134: }
|