KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > java > InternalCompiler


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.java;
31
32 import com.caucho.loader.EnvironmentClassLoader;
33 import com.caucho.log.Log;
34 import com.caucho.util.CharBuffer;
35 import com.caucho.vfs.Encoding;
36 import com.caucho.vfs.IOExceptionWrapper;
37 import com.caucho.vfs.MemoryStream;
38 import com.caucho.vfs.Path;
39 import com.caucho.vfs.ReadStream;
40 import com.caucho.vfs.WriteStream;
41
42 import java.io.IOException JavaDoc;
43 import java.io.InputStream JavaDoc;
44 import java.io.PrintWriter JavaDoc;
45 import java.lang.reflect.InvocationTargetException JavaDoc;
46 import java.lang.reflect.Method JavaDoc;
47 import java.util.ArrayList JavaDoc;
48 import java.util.logging.Level JavaDoc;
49 import java.util.logging.Logger JavaDoc;
50
51 /**
52  * Compiles Java source, returning the loaded class.
53  */

54 public class InternalCompiler extends AbstractJavaCompiler {
55   private static final Logger JavaDoc log = Log.open(InternalCompiler.class);
56   
57   private static boolean _hasCompiler; // already tested for compiler
58

59   Process JavaDoc _process;
60   String JavaDoc _userPrefix;
61   
62   boolean _isDead;
63   
64   public InternalCompiler(JavaCompiler compiler)
65   {
66     super(compiler);
67   }
68
69   protected void compileInt(String JavaDoc []path, LineMap lineMap)
70     throws IOException JavaDoc, JavaCompileException
71   {
72     if (! _hasCompiler) {
73       try {
74         Class.forName("com.sun.tools.javac.Main",
75                       false, Thread.currentThread().getContextClassLoader());
76
77         _hasCompiler = true;
78       } catch (Exception JavaDoc e) {
79         e.printStackTrace();
80         throw new JavaCompileException(L.l("Resin can't load com.sun.tools.javac.Main. Usually this means that the JDK tools.jar is missing from the classpath, possibly because of using a JRE instead of the JDK. You can either add tools.jar to the classpath or change the compiler to an external one with <java compiler='javac'/> or jikes.\n\n{0}", String.valueOf(e)));
81       }
82     }
83
84     executeInt(path, lineMap);
85   }
86
87   /**
88    * Compiles the names files.
89    */

90   private void executeInt(String JavaDoc []path, LineMap lineMap)
91     throws JavaCompileException, IOException JavaDoc
92   {
93     MemoryStream tempStream = new MemoryStream();
94     WriteStream error = new WriteStream(tempStream);
95
96     try {
97       // String parent = javaPath.getParent().getNativePath();
98

99       ArrayList JavaDoc<String JavaDoc> argList = new ArrayList JavaDoc<String JavaDoc>();
100       /* This isn't needed since srcDirName is in the classpath
101       if ("1.2".compareTo(System.getProperty("java.version")) <= 0) {
102         argList.add("-sourcepath");
103         argList.add(srcDirName);
104       }
105       */

106       argList.add("-d");
107       argList.add(_compiler.getClassDirName());
108       if (_compiler.getEncoding() != null) {
109         String JavaDoc encoding = Encoding.getJavaName(_compiler.getEncoding());
110         if (encoding != null && ! encoding.equals("ISO8859_1")) {
111           argList.add("-encoding");
112           argList.add(_compiler.getEncoding());
113         }
114       }
115       argList.add("-classpath");
116       argList.add(_compiler.getClassPath());
117       ArrayList JavaDoc<String JavaDoc> args = _compiler.getArgs();
118       if (args != null)
119     argList.addAll(args);
120
121       for (int i = 0; i < path.length; i++) {
122     Path javaPath = _compiler.getSourceDir().lookup(path[i]);
123     argList.add(javaPath.getNativePath());
124       }
125
126       if (log.isLoggable(Level.FINE)) {
127         CharBuffer msg = new CharBuffer();
128     msg.append("javac(int)");
129     for (int i = 0; i < argList.size(); i++) {
130       msg.append(" ");
131       msg.append(argList.get(i));
132     }
133
134         log.fine(msg.toString());
135       }
136
137       String JavaDoc []argArray = argList.toArray(new String JavaDoc[argList.size()]);
138
139       int status = -1;
140       
141       Thread JavaDoc thread = Thread.currentThread();
142       ClassLoader JavaDoc oldLoader = thread.getContextClassLoader();
143       try {
144     EnvironmentClassLoader env;
145     env = new EnvironmentClassLoader(ClassLoader.getSystemClassLoader());
146         thread.setContextClassLoader(env);
147
148         try {
149           Class JavaDoc cl = Class.forName("com.sun.tools.javac.Main", false, env);
150           Object JavaDoc compiler = cl.newInstance();
151           Method JavaDoc compile = null;
152
153       Object JavaDoc value = null;
154       
155       try {
156         compile = cl.getMethod("compile", new Class JavaDoc[] { String JavaDoc[].class , PrintWriter JavaDoc.class });
157         value = compile.invoke(compiler, new Object JavaDoc[] { argArray, error.getPrintWriter() });
158
159       } catch (Throwable JavaDoc e) {
160         log.log(Level.FINER, e.toString(), e);
161       }
162
163       if (compile == null) {
164         compile = cl.getMethod("compile", new Class JavaDoc[] { String JavaDoc[].class });
165         value = compile.invoke(compiler, new Object JavaDoc[] { argArray });
166       }
167
168           if (value instanceof Integer JavaDoc)
169             status = ((Integer JavaDoc) value).intValue();
170         } catch (ClassNotFoundException JavaDoc e) {
171           throw new JavaCompileException(L.l("Can't find internal Java compiler. Either configure an external compiler with <javac> or use a JDK which contains a Java compiler."));
172         } catch (NoSuchMethodException JavaDoc e) {
173           throw new JavaCompileException(e);
174         } catch (InstantiationException JavaDoc e) {
175           throw new JavaCompileException(e);
176         } catch (IllegalAccessException JavaDoc e) {
177           throw new JavaCompileException(e);
178         } catch (InvocationTargetException JavaDoc e) {
179           throw new IOExceptionWrapper(e);
180         }
181       
182     error.close();
183     tempStream.close();
184       } finally {
185         thread.setContextClassLoader(oldLoader);
186       }
187
188       ReadStream read = tempStream.openRead();
189       JavacErrorParser parser = new JavacErrorParser(_compiler.getEncoding());
190
191       String JavaDoc errors = parser.parseErrors((InputStream JavaDoc) read, lineMap);
192       read.close();
193
194       if (errors != null)
195     errors = errors.trim();
196
197       if (log.isLoggable(Level.FINE)) {
198     read = tempStream.openRead();
199     CharBuffer cb = new CharBuffer();
200     int ch;
201     while ((ch = read.read()) >= 0) {
202       cb.append((char) ch);
203     }
204     read.close();
205
206     log.fine(cb.toString());
207       }
208       else if (status == 0 && errors != null && ! errors.equals("")) {
209     final String JavaDoc msg = errors;
210     
211     new com.caucho.loader.ClassLoaderContext(_compiler.getClassLoader()) {
212       public void run()
213       {
214         log.warning(msg);
215       }
216     };
217       }
218
219       if (status != 0)
220     throw new JavaCompileException(errors);
221     } finally {
222       tempStream.destroy();
223     }
224   }
225 }
226
Popular Tags