| <!doctype html public "-//w3c//dtd html 4.0 transitional//en"> |
| <html> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> |
| <meta name="GENERATOR" content="Mozilla/4.5 [en] (Win98; I) [Netscape]"> |
| <meta name="Author" content="Build"> |
| <title>JDT - Pluggable JDKs</title> |
| </head> |
| <body> |
| |
| <h2> |
| Pluggable JDKs</h2> |
| Last revised 11:45 Friday October 19, 2001 |
| <p>Work item: pluggable JDKs</p> |
| <p>Related work item: "Support for dealing with class files generated by |
| external Java compilers like javac and jikes from an Ant script."</p> |
| <p>Related issue: remote builds</p> |
| <p>Other IDEs can claim that when Sun or IBM releases a new JDK, a developer |
| can just "plug it in" to their IDE. We would like Eclipse to be similarly |
| flexible, and be able to make a similar claim.</p> |
| <p>In practice, what does this mean? There are several different aspects.</p> |
| <ol> |
| <li> |
| The ablility to run Java programs with the JDK's JRE.</li> |
| |
| <li> |
| The ablility to compile Java source code against the JDK's class libraries.</li> |
| |
| <li> |
| The ablility to compile Java source code with the JDK's javac compiler.</li> |
| |
| <li> |
| The ablility to debug Java programs with the JDK's JDPA and JVM.</li> |
| |
| <li> |
| The ablility to browse the JDK's class library API javadoc (or perhaps |
| other release doc).</li> |
| |
| <li> |
| The ablility to run the JDK's utility programs like javap, javadoc, javah.</li> |
| </ol> |
| We will take the first four as the most important ones for Eclipse to address, |
| and look at each in turn. |
| <h3> |
| Pluggable JREs</h3> |
| This is supported in Eclipse 1.0. |
| <p>The org.eclipse.jdt.launching plug-in provides pluggable support ("vmInstallTypes" |
| extension point) for describing installed Java2-style Java runtime environments |
| and launching particular configurations of a Java virtual machine.</p> |
| <p>JDT defines a workbench preference ("Installed Java Runtime Environments") |
| so that the user can create, remove, and edit JRE definitions (i.e., instances |
| of the known VM installed types). The user chooses which one of the JRE |
| definitions is the default.</p> |
| <p>JDT also defines a JRE property for each Java project to control which |
| JRE is used to run programs in that project. By default, each project shares |
| the workspace-wide default. The user can elect to specify a JRE for that |
| project, which overrides the workspace-wide default.</p> |
| <h3> |
| Pluggable JDK class libraries</h3> |
| This is supported in Eclipse 1.0. |
| <p>JDT Core provides a reserved build classpath variable, named "JRE_LIB", |
| which gets bound to the JAR library (and associated source code ZIP) of |
| the current workspace-wide default JRE (e.g., "D:\jdk1.4\jre\lib\rt.jar" |
| with source in "D:\jdk1.4\src.zip"). By default, a classpath entry is included |
| on the build classpath of a newly created project. This library would ordinarily |
| supply the compile-time definitions of the standard class libraries used |
| when browsing and building a Java project.</p> |
| <p>The client that is not satisfied with this variable is free to remove |
| the classpath entry from the build classpath and replace it with something |
| else. The client could declare their own build classpath variable, bind |
| it to a suitable value, and include that on the build classpath instead |
| (For instance, VAME/WSDD declares a classpath variable named "IVJ_HOME" |
| and references various class libraries relative to it; e.g., "IVJ_HOME/lib/jclmax.jar".) |
| Or they could just hard-wire a library entry for a particular JRE library.</p> |
| <p>While the basic mechanism is reasonable, it is unfortunate that it is |
| tied so tightly to the default JRE. It might be more convenient if selecting |
| a different workspace-wide default JRE definition would prompt the user |
| to change the JRE_LIB classpath variable as well.</p> |
| <p>Paralleling the workbench JRE mechanism, we could consider allowing |
| the user to specify classpath variable bindings at the project level that |
| override the workspace-wide default. This would allow the user to change |
| the binding to affect just that project. Something similar can already |
| be achieved by using distinctly-named classpath variables for each project |
| (e.g., "P1_JRE_LIB" for project P1's "JRE_LIB"). So it's unclear whether |
| any interesting new usecases would be supported by this.</p> |
| <h3> |
| Pluggable Java compilers</h3> |
| Java compilers can differ along many axes: |
| <ul> |
| <li> |
| supported Java language level</li> |
| |
| <li> |
| Java bytecode version</li> |
| |
| <li> |
| quality of generated code</li> |
| |
| <li> |
| helpfulness of error messages</li> |
| |
| <li> |
| performance</li> |
| |
| <li> |
| robustness</li> |
| |
| <li> |
| product support for compiler</li> |
| </ul> |
| In the simple world of the command line compiler, it's easy to use whatever |
| Java compiler you choose to use. The command lines are substantially the |
| same, and the overt compiler behavior of translating .java source files |
| to .class files is utterly standard. |
| <p>In additional to the basic compiler functionality, there are usually |
| a number of IDE features that also need to be "language aware" (to some |
| extent), including:</p> |
| <ul> |
| <li> |
| source code editing (syntax highlighting)</li> |
| |
| <li> |
| code assist (completion, selection)</li> |
| |
| <li> |
| code reformatter</li> |
| |
| <li> |
| search</li> |
| </ul> |
| <p>The language aware features require compiler infrastructure (e.g., a scanner).</p> |
| <p>The standard Sun Java compiler has no official APIs; the compiler infrastructure |
| is not available outside the compiler. This means that Java IDEs have no |
| choice but to reimplement whatever compiler infrastructure they might need. |
| Without standard Java compiler APIs, no Java IDE can be truely pluggable |
| in these regards. The best that a Java IDE can do in the circumstances |
| is to use a pluggable Java compiler for its basic compiler functionality.</p> |
| <p>In Eclipse 1.0, the IDE's basic Java compiler functionality is provided |
| by the built-in Eclipse compiler. What would it take to make this part |
| pluggable?</p> |
| <p>In Eclipse, the basic Java compiler functionality is provided through |
| the Java builder. The Java builder is activated when its build method is |
| called. This happens when (a) an explicit Build commands requested by the |
| user, (b) the workspace performs an auto build, or (c) some plug-in instigated |
| a build programmatically.</p> |
| <p>So the first idea is that the Java builder's build method should invoke |
| a pluggable Java compiler to do a build.</p> |
| <h4> |
| Calling a pluggable javac from within the Java builder</h4> |
| <p>For a full build, this is clearly doable. The source folders mentioned |
| on the build classpath can be walked to identify all Java source files. |
| The corresponding class files in the output folder are deleted, and Java |
| problem markers are removed. The names of these source files are then passed |
| to javac as the ones to compile (large file sets perhaps broken up into |
| reasonable sized batches); the classpath passed is computed from the project's |
| build classpath; the output folder is passed as the target for the generated |
| class files. The compiler will generate class files into the target folder |
| and print text error messages to its output stream. Depending on how "standard" |
| the format of the output stream was, the Java builder might be able to |
| analyze the stream of text error messages and convert these into Java problem |
| markers associated with the offending source files (the complete stream |
| could also be saved and made available to user through some other mechanism). |
| Otherwise the net result is close to that of running the Eclipse compiler. |
| One other difference is that the Java builder would not be able to produce |
| anything resembling its current internal built state (i.e., no dependency |
| graph).</p> |
| <p>For an incremental build, it is impossible to do anything more than |
| a cursory job without proper dependency information. The Java builder is |
| passed a resource delta for the project showing which source files have |
| changed. The delta would also show that the build classpath had changed |
| (the Java builder could easily remember some classpaths between builds).</p> |
| <p>How to do an incremental build:</p> |
| <ul> |
| <li> |
| delete a source file => identify and delete the corresponding class files</li> |
| |
| <li> |
| add a source file => identify and delete corresponding class files (just |
| in case); include source file in list to be recompiled</li> |
| |
| <li> |
| change a source file => identify and delete corresponding class files; |
| include source file in list to be recompiled</li> |
| </ul> |
| <p>The compiler is called to recompile the identified list of source files. |
| The Java builder might be able to analyze the -verbose output stream to |
| discover which source files were actually compiled and update their Java |
| problem markers.</p> |
| <p>This kind of simple-minded incremental build handles many simple cases |
| (e.g., changing the body of a method, fixing javadoc comments, reformatting). |
| The results would usually be less satisfactory when the principal structure |
| of class is changed because any dependent source files do not get recompiled, |
| which may lead to incompatible sets of binaries class files. The developer |
| would need to be educated about when to be asking for a full build. Many |
| will already be familiar with these rules from using other Java IDEs. With |
| a Java compiler that does not produce dependency information, it is hard |
| for an IDE with pluggable Java compilers to do any better.</p> |
| <p>Autobuild is just an incremental build that is triggered automatically. |
| Note that the user may find it intolerable to run with autobuild enabled |
| if the overhead for invoking the pluggable compiler is high (which it is |
| likely to be if a separate JVM would need to be launched).</p> |
| <p>The conclusion is that this is feasible, although autobuilding may be |
| intolerable. As long as the pluggable Java compiler was very javac-like |
| in terms of command line options and format of generated error messages, |
| it should be possible to use it to build a Java project.</p> |
| <h4> |
| Calling an Ant script instead of the Java builder</h4> |
| <p>An even more flexible approach would be to allow a Java project to be configured |
| with a generic Ant-based incremental project builder instead of the standard |
| Java builder. The Ant-based builder is described in a separate 2.0 Platform |
| Core feature proposal.</p> |
| <p>All of the above considerations would still apply; the only real difference |
| is that everything is implemented in Ant terms.</p> |
| <h3> |
| Pluggable JDPA Debuggers</h3> |
| <p>Eclipse reimplements the JPDA debugger front end; it does not use the JDI |
| implementation supplied by Sun. Even if it did use Sun JDI, it still would |
| be work for the Eclipse debugger to capitalize on any new debugger functionality |
| thereby introduced. So the debugger front end is upgradeable, but not pluggable.</p> |
| <p>The JDPA debugger back end is logically part of the Java runtime environment, |
| and ships with the IBM and Sun J2SE JDKs since 1.3. So this part is already |
| pluggable.</p> |
| </body> |
| </html> |