Work item: pluggable JDKs
Related work item: "Support for dealing with class files generated by external Java compilers like javac and jikes from an Ant script."
Related issue: remote builds
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.
In practice, what does this mean? There are several different aspects.
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.
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.
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.
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.
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.
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.
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.
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:
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.
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?
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.
So the first idea is that the Java builder's build method should invoke a pluggable Java compiler to do a build.
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).
How to do an incremental build:
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.
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).
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.
All of the above considerations would still apply; the only real difference is that everything is implemented in Ant terms.
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.