JDK-6297388 : JSR 199: compile against a class loader
  • Type: Enhancement
  • Component: tools
  • Sub-Component: javac
  • Affected Version: javadb_10.0,6
  • Priority: P4
  • Status: Resolved
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2005-07-15
  • Updated: 2015-06-26
  • Resolved: 2015-06-26
Related Reports
Blocks :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
a problem JSP Containers face is to compile generated JSP Page Servlets
against the classpath that makes up a web application. There is no way
to find out the locations of the classes that make up the classpath.
While it is possible for WEB-INF/classes and WEB-INF/lib, the JSP
container needs intimate knowledge of the servlet container's class
loading mechanism to add the rest (for example, the location of the
servlet-api jar).

This dependency on the servlet container has hindered the community to
develop a portable, drop-in JSP container. While you can argue that JSP
and Servlet containers are intimately coupled, any web framework that
wants to compile code would face the same problem.

An alternative, pioneered by the Cocoon community, and which I believe
is being pursued by Jasper in Tomcat 5.5, is to use a compiler that
resolves its classpath against a _classloader_ instead of a
_filesystem_, using ClassLoader#getResource instead of java.io.File.
Eclipse's Compiler has successfully been used to do this.

While the JavaFileManager in principle looks like it could be adapted to
a ClassLoader, it requires the "list" operation, an operation a
ClassLoader cannot fulfill. Is listing all classes in a package
necessary for this compiler to work? If so, a "Compile in current
classloader", or more specific, "Compile in this webapp" will not be
possible with JSR 199 which would be a shame. I remember that I once
tried to make javac do this and I stumbled over this exact requirement
before; eclipse's jdt did not need it.




###@###.### 2005-07-15 14:41:52 GMT

Closing this as duplicate of https://bugs.openjdk.java.net/browse/JDK-8065667 - All action is happening there.

That Eclipse supports compiling against a class loader is an urban legend. I see nowhere in eclipse compiler any relevant use of: java.lang.ClassLoader.getResource(String) java.lang.ClassLoader.getResources(String) java.lang.ClassLoader.getSystemResource(String) java.lang.ClassLoader.getSystemResources(String) java.lang.ClassLoader.getResourceAsStream(String) or java.lang.ClassLoader.getSystemResourceAsStream(String) What Eclipse does is simply define some APIs that make it somewhat easier to implement compiling against class loader - its INameEnvironment can me more readily implemented by clients than javac's (and JSR 199s) JavaFIleManager - which requires ability to enumerate the contents of a package which may not be possible with arbitrary class loaders.

Removing fix version, the blocking issue doesn't have a fix version yet, and might not be implemented in 8, therefore this enhancements will probably not be implemented in 8.

As much as we want to do this, we are blocked by the lack of the necessary underlying API from ClassLoader.

EVALUATION The problem here is that the JavaFileManager API provides a "list" operation, which is used internally by the impl class JavacFileManager to determine the contents of a package when processing import-on-demand. (e.g. "import java.util.*;") But, the ClassLoader API does not support a list operation in any form. There is a partial workaround, and that's as good as it will get. We can change javac internals to not use the list operation. This means rewriting the Scope system so that scopes are built more lazily -- especially the scopes for "import on demand". That will allow most compilations to be feasible when using a class loader. The problem is that the list operation is exposed through the public API for jsr199 (compiler API) and jsr269 (annotation processing). Wth these API, a client can provide "plugin" code that may want to list the contents of a package. If a Location is provided that uses a ClassLoader, that operation will fail (as in get something like UnsupportedOperationException.) We will have to change the spec of list to allow that possibility, and/or provide additional methods to determine if a Location supports the list method.

EVALUATION Currently, the infrastructure of javac is not geared towards this RFE. However, it is reasonable to expect JSR 199 to include this possibilty for at least two reasons: * other compilers might have different infrastructure * JSR 199 should be able to accomodate future growth

WORK AROUND While the abstract ClassLoader API may not easily support the current JavaFileManager, it is likely that an implementation of ClassLoader would be able to. Making a ClassLoader that loads from a jar file, for example, is not a big deal, and such an implementation of ClassLoader could support the JavaFileManager interface as well.

SUGGESTED FIX JavaFileManager should have a method for resolving binary class names directly. ###@###.### 2005-07-15 14:51:12 GMT