KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > ejb > codegen > JavaCompiler


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * JavaCompiler.java
26  *
27  * Created on June 22, 2002, 8:56 PM
28  *
29  * @author bnevins
30  * @version $Revision: 1.3 $
31  * <BR> <I>$Source: /cvs/glassfish/appserv-core/src/java/com/sun/ejb/codegen/JavaCompiler.java,v $
32  *
33  */

34
35 package com.sun.ejb.codegen;
36
37 import java.io.*;
38 import java.util.*;
39 import java.util.logging.*;
40 import com.sun.enterprise.util.OS;
41 import com.sun.enterprise.util.StringUtils;
42 import com.sun.enterprise.util.i18n.StringManager;
43 import com.sun.enterprise.util.io.FileUtils;
44 import com.sun.enterprise.server.Constants;
45 import com.sun.tools.javac.Main;
46
47 class JavaCompiler extends Compiler JavaDoc
48 {
49     private static final String JavaDoc JAVAC_EXT_DIRS_OPTION = "-extdirs";
50     private static final String JavaDoc JAVAC_OUT_OF_PROCESS =
51                                 "com.sun.aas.deployment.javacoutofprocess";
52
53
54     JavaCompiler(List theOptions, List theFiles) throws JavaCompilerException
55     {
56         super(theOptions, theFiles);
57     }
58
59     ///////////////////////////////////////////////////////////////////////////
60

61     protected void internal_compile() throws JavaCompilerException, ProcessExecutorException
62     {
63         // note: we are NOT catching Exceptions and then trying the next one.
64
// An Exception means there was a compile error and it would be a waste of
65
// time to run another compile.
66
// if they return true -- it means the facility exists AND everything compiled OK
67
// note: only allow JavaCompilerException out of here -- catch everything else
68
// and wrap it!!
69

70         if(userCompile()) {
71             return;
72                 }
73
74         if(fastjavacCompile()) {
75             return;
76                 }
77
78         javacCompile();
79     }
80     
81     ///////////////////////////////////////////////////////////////////////////
82

83     private boolean userCompile() throws ProcessExecutorException
84     {
85         if(userExe == null)
86             return false;
87         
88         ArrayList cmd = new ArrayList();
89         cmd.add(userExe.getPath());
90                 cmd.add(JAVAC_EXT_DIRS_OPTION);
91                 cmd.add(System.getProperty(JAVA_EXT_DIRS_SYS_PROP));
92         cmd.addAll(userOptions);
93         cmd.addAll(options);
94         cmd.addAll(files);
95         
96         String JavaDoc[] cmds = new String JavaDoc[cmd.size()];
97         cmds = (String JavaDoc[])cmd.toArray(cmds);
98         runProcess(cmds, getUserSpecifiedCompilerTimeout() * files.size());
99         logCompilerName(userExe.getName());
100         return true;
101     }
102     
103     //////////////////////////////////////////////////////////////////////////
104

105     private boolean fastjavacCompile() throws ProcessExecutorException
106     {
107         if(fastExe == null || jdkDir == null)
108             return false;
109
110         ArrayList cmd = new ArrayList();
111         cmd.add(fastExe.getPath());
112         cmd.add("-jdk");
113         cmd.add(jdkDir.getPath());
114         cmd.addAll(options);
115         addJavaFiles(cmd);
116         String JavaDoc[] cmds = new String JavaDoc[cmd.size()];
117         cmds = (String JavaDoc[])cmd.toArray(cmds);
118         runProcess(cmds, getFastjavacTimeout() * files.size());
119         logCompilerName("fastjavac");
120         return true;
121     }
122
123     ///////////////////////////////////////////////////////////////////////////
124

125     private boolean javacCompile() throws JavaCompilerException,
126                                               ProcessExecutorException
127     {
128         if(javacExe == null)
129             return false;
130         
131                 boolean outOfProcess =
132                     Boolean.getBoolean(JAVAC_OUT_OF_PROCESS);
133
134         ArrayList cmd = new ArrayList();
135                 if (outOfProcess) {
136                     cmd.add(javacExe.getPath());
137                 }
138                 cmd.add(JAVAC_EXT_DIRS_OPTION);
139                 cmd.add(System.getProperty(JAVA_EXT_DIRS_SYS_PROP));
140                 cmd.addAll(options);
141             addJavaFiles(cmd);
142             String JavaDoc[] cmds = new String JavaDoc[cmd.size()];
143             cmds = (String JavaDoc[])cmd.toArray(cmds);
144
145                 if (outOfProcess) {
146                     runProcess(cmds, getJavacTimeout() * files.size());
147                 } else {
148                     try {
149                         ByteArrayOutputStream bos =
150                             new ByteArrayOutputStream();
151                         PrintWriter pw = new PrintWriter(bos);
152                         Main compiler = new Main();
153                         int ret = compiler.compile(cmds, pw);
154                         if (ret != 0) {
155                             byte[] errorBytes = bos.toByteArray();
156                             String JavaDoc errorString = new String JavaDoc(errorBytes);
157                             throw new JavaCompilerException(
158                                 "java_compiler.error", "Native compiler returned an error: {0}\nError messages are: {1}", new Object JavaDoc[] { new Integer JavaDoc (ret), errorString } );
159                         }
160                     }
161                     catch(JavaCompilerException jce) {
162                         throw jce;
163                     }
164                     catch(Throwable JavaDoc t)
165                     {
166                         throw new JavaCompilerException(
167                             "java_compiler.unknown_exception",
168                             "JavaC compiler threw an Exception", t);
169                     }
170                 }
171         logCompilerName("javac");
172         return true;
173     }
174     
175     ///////////////////////////////////////////////////////////////////////////
176

177     protected void internal_init()
178     {
179         fastExe = null;
180         javacExe = null;
181         userExe = null;
182         userOptions = new ArrayList();
183         
184         initUserCompiler();
185         initFastjavac();
186         initJavac();
187         logger.log(Level.FINE, "fastExe: " + ((fastExe == null) ? "null" : fastExe.getPath()) );
188         logger.log(Level.FINE, "javacExe: " + ((javacExe == null) ? "null" : javacExe.getPath()) );
189         logger.log(Level.FINE, "jdkDir: " + ((jdkDir == null) ? "null" : jdkDir.getPath()) );
190     }
191     
192     ///////////////////////////////////////////////////////////////////////////
193

194     private void initUserCompiler()
195     {
196         String JavaDoc userSpecified = getSystemPropertyIgnoreCase(Constants.USER_SPECIFIED_COMPILER);
197         
198         if(!StringUtils.ok(userSpecified))
199             return;
200         
201         userExe = new File(userSpecified);
202
203         if(!userExe.exists())
204         {
205             String JavaDoc msg = localStrings.getStringWithDefault(
206                 "java_compiler.bad_user_compiler",
207                 "Can't locate user-specified Java Compiler for deployment. "
208                     +"Environmental Variable= {0}, Value = {1}",
209                 new Object JavaDoc[] { Constants.USER_SPECIFIED_COMPILER, userSpecified } );
210
211             logger.warning(msg);
212             userExe = null;
213             return;
214         }
215         
216         // note: it is difficult to handle spaces inside options.
217
// at least without requiring the user to specify the args as:
218
// xxx1, xxx2, xxx3, etc. That's too painful for them. Or I could
219
// parse out quote-delimited Strings. Maybe later. What
220
// are the chances that they will use spaces in filenames anyways?
221

222         userExe = FileUtils.safeGetCanonicalFile(userExe);
223         String JavaDoc opts = getSystemPropertyIgnoreCase(Constants.USER_SPECIFIED_COMPILER_OPTIONS);
224         
225         if(!StringUtils.ok(opts))
226             return;
227         
228         StringTokenizer tok = new StringTokenizer(opts);
229         
230         while(tok.hasMoreTokens())
231         {
232             userOptions.add(tok.nextToken());
233         }
234     }
235     
236     
237     ///////////////////////////////////////////////////////////////////////////
238

239     private void initFastjavac()
240     {
241         if(installRoot == null || jdkDir == null)
242             return;
243         
244         String JavaDoc fastName;
245         /*
246         // WBN -- Allow config of fastjavac in the environment
247         String fastName = System.getProperty(Constants.FASTJAVAC_COMPILER);
248         
249         if(StringUtils.ok(fastName))
250         {
251             fastExe = new File(fastName);
252
253             if(fastExe.exists())
254             {
255                 fastExe = FileUtils.safeGetCanonicalFile(fastExe);
256                 return;
257             }
258             fastExe = null;
259         }
260         */

261         
262         if(OS.isWindows())
263             fastName = "fastjavac.exe";
264         else if(OS.isSun())
265             fastName = "fastjavac.sun";
266         else if(OS.isLinux())
267             fastName = "fastjavac.linux";
268         else
269             fastName = null;
270         
271         if(fastName == null)
272             return;
273
274         // if fastjavac app exists -- set it
275
fastExe = new File(installRoot + "/studio4/bin/fastjavac/" + fastName); //now named studio4
276

277         if(fastExe.exists())
278             fastExe = FileUtils.safeGetCanonicalFile(fastExe);
279         else
280             fastExe = null;
281     }
282     
283     ///////////////////////////////////////////////////////////////////////////
284

285     private void initJavac()
286     {
287         if(jdkDir == null)
288             return;
289         
290         String JavaDoc javacName;
291         
292         if(OS.isWindows())
293         {
294             javacName = "javac.exe";
295         }
296         else
297         {
298             javacName = "javac";
299         }
300
301         javacExe = new File(jdkDir, "/bin/" + javacName);
302
303         if(javacExe.exists())
304             javacExe = FileUtils.safeGetCanonicalFile(javacExe);
305         else
306             javacExe = null;
307     }
308
309     /**
310      * Returns the timeout, in milliseconds, for each java file.
311      * The compiler calling code will multiply this value by the
312      * number of java files. If the compiler takes longer than
313      * this amount of time the process will be killed.
314      * This is to avoid hangs.
315      *
316      * <p>For flexibility, a environmental variable is checked first. Failing that,
317      * it will use the hard-coded default value.
318      *
319      * <p>This method caches the value of timeout in "fastJavacTimeout" variable to prevent
320          * memory leak seen in the System.getProperty method in Compiler.java
321      *
322      * @return The timeout, in milliseconds, for each java file
323      */

324     private static int getFastjavacTimeout()
325     {
326         if (fastJavacTimeout < 0 )
327         {
328             fastJavacTimeout = getTimeout(Constants.FASTJAVAC_TIMEOUT_MS, Constants.DEFAULT_FASTJAVAC_TIMEOUT_MS, 1000, 300000);
329         }
330         return fastJavacTimeout;
331     }
332
333     /** Returns the timeout, in milliseconds, for each java file.
334      * The compiler calling code will multiply this value by the
335      * number of java files. If the compiler takes longer than
336      * this amount of time the process will be killed.
337      * This is to avoid hangs.
338      *
339      * <p>For flexibility, a environmental variable is checked first. Failing that,
340      * it will use the hard-coded default value.
341      *
342      * <p>This method caches the value of timeout in "javacTimeout" variable to prevent
343          * memory leak seen in the System.getProperty method in Compiler.java
344      *
345      * @return The timeout, in milliseconds, for each java file
346      */

347     private static int getJavacTimeout()
348     {
349         if (javacTimeout < 0 )
350         {
351             javacTimeout = getTimeout(Constants.JAVAC_TIMEOUT_MS, Constants.DEFAULT_JAVAC_TIMEOUT_MS, 1000, 900000);
352         }
353         return javacTimeout;
354     }
355
356     /** Returns the timeout, in milliseconds, for each java file.
357      * The compiler calling code will multiply this value by the
358      * number of java files. If the compiler takes longer than
359      * this amount of time the process will be killed.
360      * This is to avoid hangs.
361      *
362      * <p>For flexibility, a environmental variable is checked first. Failing that,
363      * it will use the hard-coded default value.
364      *
365      * <p>This method caches the value of timeout in "userTimeout" variable to prevent
366          * memory leak seen in the System.getProperty method in Compiler.java
367      *
368      * @return The timeout, in milliseconds, for each java file
369      */

370     private static int getUserSpecifiedCompilerTimeout()
371     {
372         if (userTimeout < 0 )
373         {
374             userTimeout = getTimeout(Constants.USER_SPECIFIED_COMPILER_TIMEOUT_MS, Constants.DEFAULT_USER_SPECIFIED_COMPILER_TIMEOUT_MS, 1000, 900000);
375         }
376         return userTimeout;
377     }
378     
379     ///////////////////////////////////////////////////////////////////////////
380

381     private File userExe;
382     private File fastExe;
383     private File javacExe;
384     private List userOptions;
385
386     // used for caching timeouts to prevent memory leaks. must be initialized to -1.
387
private static int fastJavacTimeout = -1;
388     private static int javacTimeout = -1;
389     private static int userTimeout = -1;
390
391     ///////////////////////////////////////////////////////////////////////////
392
/* testing code...
393     public static void main(String[] args)
394     {
395         System.out.println("Test 1: install-root == C:/ias7 and JAVA_HOME not set");
396         System.setProperty(Constants.INSTALL_ROOT, "C:/ias7");
397         test();
398         System.out.println("Test 2: install-root == C:/ias7 and JAVA_HOME == c:/jdk1.4");
399         System.setProperty("JAVA_HOME", "C:/jdk1.4");
400         test();
401     }
402     
403     
404     ///////////////////////////////////////////////////////////////////////////
405
406     public static void test()
407     {
408         List opt = new ArrayList();
409         List f = new ArrayList();
410     
411         opt.add("-d");
412         opt.add("c:/tmp/crap");
413         opt.add("-g");
414         f.add("c:/src/java/junk/Crap.java");
415     
416         try
417         {
418             JavaCompiler jc = new JavaCompiler(opt, f);
419             logger.log(Level.SEVERE, "fastExe: " + ((jc.fastExe == null) ? "null" : jc.fastExe.getPath()) );
420             logger.log(Level.SEVERE, "javacExe: " + ((jc.javacExe == null) ? "null" : jc.javacExe.getPath()) );
421             logger.log(Level.SEVERE, "jdkDir: " + ((jc.jdkDir == null) ? "null" : jc.jdkDir.getPath()) );
422             jc.compile();
423         }
424         catch(Exception e)
425         {
426             e.printStackTrace();
427         }
428     }
429  **/

430 }
431
432
Popular Tags