Bug 42838 - Support for JSR 199: Java Compiler API
Summary: Support for JSR 199: Java Compiler API
Status: NEW
Alias: None
Product: Ant
Classification: Unclassified
Component: Core tasks (show other bugs)
Version: 1.7.0
Hardware: All All
: P3 enhancement (vote)
Target Milestone: ---
Assignee: Ant Notifications List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-07-09 01:07 UTC by Alexey Gavrilov
Modified: 2008-02-22 12:18 UTC (History)
3 users (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alexey Gavrilov 2007-07-09 01:07:55 UTC
Please provide support for JSR 199: Java Compiler API.

Java Compiler API (JSR 199) is a required part of Java SE 6 platform which
provides the interface to invoke Java™ programming language compilers. Using
this interface can potentially reduce overhead of scanning the file system and
reading jar files while sharing a file manager across compilation tasks. Please
see details at http://java.sun.com/javase/6/docs/api/javax/tools/JavaCompiler.html
Comment 1 Steve Loughran 2007-07-09 03:32:05 UTC
one question: why? Ant already has lots of support for the existing javac apis,
to the extent that we're actually used behind the scenes in a lot of places.
What is so compelling about the new API that we need to add a new implementation
and the test cases to match?

The only thing would make it compelling to me would be if non-forking javac
would stop leaking very large (multi-megabyte) static data structures. Is there
any discussion in that in the API? Whenever we reported that problem to sun in
the past, it was always dismissed as a WONTFIX "you shouldnt be running javac
in-process".
Comment 2 Jonathan Gibbons 2007-07-09 07:16:48 UTC
(In reply to comment #1)
> one question: why? Ant already has lots of support for the existing javac apis,
> to the extent that we're actually used behind the scenes in a lot of places.
> What is so compelling about the new API that we need to add a new implementation
> and the test cases to match?
> 
> The only thing would make it compelling to me would be if non-forking javac
> would stop leaking very large (multi-megabyte) static data structures. Is there
> any discussion in that in the API? Whenever we reported that problem to sun in
> the past, it was always dismissed as a WONTFIX "you shouldnt be running javac
> in-process".

javac should no longer leak data as you describe. If it does, that would be regarded as a bug that would 
be fixed. JSR199 is a specific response to the demand to be able to run javac (and related tools) in 
process and reflects a commitment to that mode of operation. In addition, the JSR 199 API gives better 
OO access to the diagnostics generated by the compiler. It also provides support for reading and 
writing files from alternate storage media (e.g. memory, zip files, etc) through the use of the 
JavaFileManager.
Comment 3 Alexey Gavrilov 2007-07-09 13:19:16 UTC
JSR199 is the interface required by the spec for any conformant Java 6 (and
above) compiler. 

JSR199 provides "in-process" support for JSR269: Annotation Processing API
(javax.annotation.processing, javax.lang.model.*)

JSR199 provides support for caching resources, such as rt.jar, across
compilation tasks through sharing the JavaFileManager. This can improve
performance in cases of multiply javac invocations.

JSR199 provides a standard way of plugging in alternative compilers or tools
through the service provider mechanism.
Comment 4 Jeffrey E. Care 2007-07-09 13:28:48 UTC
Yeah yeah yeah, we get it: JSR 199 is great.

It's just too bad that it took until __Java 6__ to get all these great things.
Comment 5 Alexey Solofnenko 2007-07-09 18:18:41 UTC
(In reply to comment #4)
> Yeah yeah yeah, we get it: JSR 199 is great.
> 
> It's just too bad that it took until __Java 6__ to get all these great things.

So if the current JVM is __Java 6__, then using new API would be a right thing
to do.
Comment 6 Jeffrey E. Care 2007-07-09 18:42:35 UTC
(In reply to comment #5)

> So if the current JVM is __Java 6__, then using new API would be a right thing
> to do.

I suppose that depends on your definition of "current". Unless I missed
something, Ant is still supporting previous JVMs, so that means whomever
implements support for this JSR is going to have to pull out the usual bag of
tricks to check for JDK versions, etc.

I'm not suggesting that it's not worthwhile or that Ant shouldn't adopt this;
I'm just trying to temper the rampant enthusiasm by pointing out that this JSR
is just a __little__ bit late in coming...
Comment 7 Alexey Solofnenko 2007-07-09 21:06:44 UTC
(In reply to comment #6)

By "current" I meant the JVM executing ANT. The code could be something like that:

if (availableClass("javax.tools.JavaCompiler")) JSR199Adapter.javac(parameters);
else legacyAdapter.javac(parameters);
Comment 8 Steve Loughran 2007-07-10 03:08:51 UTC
1. yes, I am in favour of support for this. Anything that stops javac from
holding on to 10MB structures, alongside the 13MB structures that RMIC likes to
hold on two, would be welcome. 

2. It would be implemented as a new adapter behind the javac facade, which
already has support for msjvc, jikes, javac classic, javac modern.

3. the api implementation would have to use reflection so as to build on earlier
JVMs, and to degrade gracefully.

4. it would need tests and documentation; tests that only run on java1.6+

5. I would not make this the default; we'd leave it as is, maybe add a new
adapter "java6", and one alongside "latest" that always tries to use the most
modern adapter (i.e. on java7 it reserves the right to use something else)

Contributions of code tests and docs welcome.
Comment 9 Jesse Glick 2007-07-10 11:54:34 UTC
(In reply to comment #8)
> 3. the api implementation would have to use reflection so as to build on
> earlier JVMs

I suspect the number of calls to the JSR APIs (and callbacks for log collection)
would make it impractical to use reflection. Better to either require JDK 6+ to
build (excluding these classes on earlier JDKs), possibly putting it in a
separate source tree; or create a set of stub classes for the subset of the JSR
API which is needed.

> and to degrade gracefully.

Obviously the impl would not be loaded until the existence of a token JSR 199
class had been confirmed.

> 4. it would need tests and documentation; tests that only run on java1.6+

In fact you can run the compiler through JSR 199 on JDK 5, if you get the right
classes from

  http://openjdk.java.net/groups/compiler/

Just a possibility to keep in mind.

> 5. I would not make this the default

I certainly would, for people running JDK 6+. This is the official compiler API
and there is no reason to use a deprecated and unsupported backdoor call when
the API is available.
Comment 10 Alexey Solofnenko 2007-07-10 12:16:58 UTC
(In reply to comment #9)
I also agree with that.

We need to require newer Java to build ANT to have newer features supported. We
should only use reflection to see if the newer classes are available (and do not
check for JDK version).

After that we will just compile different directories with different
source/target JVM levers. 

And I would expect new JSR199 APIs to be used by default, if available.
Comment 11 Steve Loughran 2007-07-11 06:34:00 UTC
Well, I suppose we could cut a release on Java6, provided builds on earlier
platforms (a) skip that package and (b) stick with the 'modern' compiler on
java6+...we'd still be able to load the new compiler using delegation.

incidentally, does the new API let us hook in to the output better, so we can
log messages at different levels?
Comment 12 Jonathan Gibbons 2007-07-11 07:27:56 UTC
(In reply to comment #9)

> 
> I certainly would, for people running JDK 6+. This is the official compiler API
> and there is no reason to use a deprecated and unsupported backdoor call when
> the API is available.

For the record, the API at com.sun.tools.javac.Main (which I assume the javac
task is using) is not an deprecated and unsupported backdoor call. It is a
supported entry point, and not deprecated.
Comment 13 Jonathan Gibbons 2007-07-11 07:32:17 UTC
(In reply to comment #11)
> incidentally, does the new API let us hook in to the output better, so we can
> log messages at different levels?

Yes. Most messages are reported as "Diagnostic" objects to a
"DiagnosticListener". The Diagnostic objects have a Kind (NOTE, WARNING, ERROR)
etc. They also provide detailed information about the location of the issue,
when appropriate, giving the file in question, and the character offset within
the file. A few messages, such as -version and -usage info do not fall into this
category and are reported to a log PrintWriter.