Bug 527260 - [9] need an equivalent option to the javac --release option
Summary: [9] need an equivalent option to the javac --release option
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.7   Edit
Hardware: PC Mac OS X
: P3 normal (vote)
Target Milestone: 4.7.2   Edit
Assignee: Jay Arthanareeswaran CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 527569
  Show dependency tree
 
Reported: 2017-11-14 11:12 EST by Thomas Watson CLA
Modified: 2018-02-15 16:35 EST (History)
6 users (show)

See Also:
daniel_megert: pmc_approved+
stephan.herrmann: review+
manoj.palat: review+
sasikanth.bharadwaj: review+


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Watson CLA 2017-11-14 11:12:41 EST
In Java 9 there is a new javac option called --release.  Here is the --help info from javac:

--release <release>
        Compile for a specific VM version. Supported targets: 6, 7, 8, 9

On the surface this appears to only be a convenience option to replace -source and -target flags.  But it is more than that.  It also allows you to 

The javac doc gives a slightly different description [1]:

--release release

    Compiles against the public, supported and documented API for a specific VM version. Supported release targets are 6, 7, 8, and 9.

But there are more informative descriptions found in stackoverflow [2].  It looks like Java 9 is shipping some form of data that includes signatures of the older release targets.  It seems that JDT should be able to have similar support that can read these older signatures from the Java 9 installation.


[1] https://docs.oracle.com/javase/9/tools/javac.htm
[2] https://stackoverflow.com/questions/43102787/what-is-the-release-flag-in-the-java-9-compiler
Comment 1 Thomas Watson CLA 2017-11-14 11:36:20 EST
Also see http://openjdk.java.net/jeps/247

It appears there is a file in the JDK: lib/ct.sym that has different subfolders for the various releases supported by the --release option.
Comment 2 Jay Arthanareeswaran CLA 2017-11-16 13:25:55 EST
(In reply to Thomas Watson from comment #1)
> Also see http://openjdk.java.net/jeps/247
> 
> It appears there is a file in the JDK: lib/ct.sym that has different
> subfolders for the various releases supported by the --release option.

I can open that file with Zip file system provider. And there is at least one sub folder starting with "6". And within these sub folders, we have package structure and stripped down class files. The files have their extension .class replaced by .sig, but otherwise, I can make ECJ read and use them for compilation. The classes that didn't change across versions are put in shared folders. For e.g. folder "876" contains classes that are to be used for -release options "8", "7" and "6".

Only open question I have is this: Will this file be available in a JRE as well?
Comment 3 Eclipse Genie CLA 2017-11-16 14:13:10 EST
New Gerrit change created: https://git.eclipse.org/r/111741
Comment 4 Jay Arthanareeswaran CLA 2017-11-16 14:18:31 EST
(In reply to Eclipse Genie from comment #3)
> New Gerrit change created: https://git.eclipse.org/r/111741

Mostly working for the command line compiler, but still a work in progress. Valid and invalid combination of options mentioned in JEP 247 to be tested and fixed if required. Also need to see what is required for JSR 199.
Comment 5 Stephan Herrmann CLA 2017-11-16 14:28:06 EST
(In reply to Jay Arthanareeswaran from comment #2)
> Only open question I have is this: Will this file be available in a JRE as
> well?

I thought Java 9 is only distributed in one format, no JRE / JDK distinction any more?
Comment 6 Jay Arthanareeswaran CLA 2017-11-17 01:13:23 EST
(In reply to Stephan Herrmann from comment #5)
> (In reply to Jay Arthanareeswaran from comment #2)
> > Only open question I have is this: Will this file be available in a JRE as
> > well?
> 
> I thought Java 9 is only distributed in one format, no JRE / JDK distinction
> any more?

Good point. So, that answers it then.
Comment 7 Jay Arthanareeswaran CLA 2017-11-17 02:54:16 EST
I posted a new version of the patch. Some changes requires with respect to options and JSR 199 implementation. But both command line and API interfaces are supporting this feature with this patch.

I am still looking to add more tests. Meanwhile, would be nice if this can be reviewed.
Comment 8 Jay Arthanareeswaran CLA 2017-11-17 02:57:35 EST
I agree some of the names used for new classes and variables are weird (for e.g. class ClasspathJep247). Some better name suggestions are welcome.
Comment 9 Manoj N Palat CLA 2017-11-17 05:13:04 EST
(In reply to Jay Arthanareeswaran from comment #7)

> I am still looking to add more tests. Meanwhile, would be nice if this can
> be reviewed.

@Jay: On expansion on ct.sym of 181 I see the following:
6  7  76  78  8  87  876  9 
In the light of comment 2, there are combinations and there is a 78 as well as 87. I don't see these combination folders processed in findClass of ClasspathJep247 - please point to the appropriate code if it exists - probably I missed.
Comment 10 Jay Arthanareeswaran CLA 2017-11-17 05:38:03 EST
(In reply to Manoj Palat from comment #9)
> @Jay: On expansion on ct.sym of 181 I see the following:
> 6  7  76  78  8  87  876  9 
> In the light of comment 2, there are combinations and there is a 78 as well
> as 87. I don't see these combination folders processed in findClass of
> ClasspathJep247 - please point to the appropriate code if it exists -
> probably I missed.

I missed the 78 and 87 existing together. Frankly, I have no idea what that could mean. I don't find much help in the available documents. Perhaps we should checkw with the experts.

BTW, the latest patch includes some fine tuning and few more tests including the test cases from bug 526997.
Comment 11 Manoj N Palat CLA 2017-11-20 01:59:05 EST
--release need to be shown when -h is used
Comment 12 Manoj N Palat CLA 2017-11-20 03:21:02 EST
issue: ecj compiles if --release some value that starts with 6, for eg 60, 666 etc.

$ java9 -jar ecj_all.jar --release 60 X.java

For the same input javac9 gives an error.

$ javac9 --release 60 X.java
javac: release version 60 not supported
Usage: javac <options> <source files>
use --help for a list of possible options
Comment 13 Jay Arthanareeswaran CLA 2017-11-20 03:56:35 EST
(In reply to Manoj Palat from comment #12)
> issue: ecj compiles if --release some value that starts with 6, for eg 60,
> 666 etc.

Good catch. In the patch, I take only the first char of the release string and ignore the trailing ones. Should be straight forward, but let me study this a bit more. The problem is, these release strings ("6", "7", "8" etc.) don't follow the same protocol as the compliance, source level (1.6, 1.7).
Comment 14 Jay Arthanareeswaran CLA 2017-11-20 05:44:57 EST
(In reply to Jay Arthanareeswaran from comment #13)
> (In reply to Manoj Palat from comment #12)
> > issue: ecj compiles if --release some value that starts with 6, for eg 60,
> > 666 etc.
> 
> Good catch. In the patch, I take only the first char of the release string
> and ignore the trailing ones. Should be straight forward, but let me study
> this a bit more. The problem is, these release strings ("6", "7", "8" etc.)
> don't follow the same protocol as the compliance, source level (1.6, 1.7).

Will add this in the next patch.
Comment 15 Sasikanth Bharadwaj CLA 2017-11-21 03:01:38 EST
We already have the compliance shortcut option, which I believe should be invalid when release option is used, or should check the release version for incompatibilities. Right now, using - 8 --release 7 results in order dependent behavior. Other than that, I find the patch good. +1 from me
Comment 16 Stephan Herrmann CLA 2017-11-21 04:22:52 EST
Regarding --limit-modules:

* when the option is given more than once
  - javac only uses the last value
  - ecj with this patch accumulates all values

I don't see this specified in JEP 261 nor the javac man page, so we actually have several legal options:
  (1) keep our implementation
  (2) adjust our implementation to javac
      (a) additionally issue a warning that previous values will be ignored 
I believe, (2.a) would be optimal for our users.

Obviously, a specification that defines this would be highly desirable.

We can keep (1) for 4.7.2 and further improve in master.
Comment 17 Stephan Herrmann CLA 2017-11-21 04:39:49 EST
More differences regarding --limit-modules:

* javac implicitly adds java.base
* ecj with limit-modules lacking java.base gives:
    The type java.lang.Object cannot be resolved. It is indirectly referenced from required .class files
=> This could be seen as lack of computing the transitive closure, because any --limit-modules X should pull in dependencies of X, which always contains java.base
=> I hold this to be important


* in javac limit-modules can hide user modules on the modulepath, too
* in ecj limit-modules only affects system modules
=> JEP 261 does not restrict this option to system modules.
=> Filtering individual modules from a directory holding many compiled modules _could_ be useful.
=> Should be fixed but IMHO this has secondary importance.
Comment 18 Stephan Herrmann CLA 2017-11-21 04:44:19 EST
(In reply to Stephan Herrmann from comment #17)
> More differences regarding --limit-modules:
> 
> * javac implicitly adds java.base
> * ecj with limit-modules lacking java.base gives:
>     The type java.lang.Object cannot be resolved. It is indirectly
> referenced from required .class files
> => This could be seen as lack of computing the transitive closure, because
> any --limit-modules X should pull in dependencies of X, which always
> contains java.base

Corresponding TODO in ClasspathJrt.getModuleNames():
// TODO: implement algo from JEP 261 (root selection & transitive closure)


See also bug 526110 comment #0:
> (In reply to Stephan Herrmann from bug 487421 comment #48)
> > [...]
> > The algorithm itself involves two phases:
> > 
> > - if no explicit limit-modules, compute the default
> >   see JavaProject.internalDefaultRootModules()
> > 
> > - either way compute the transitive closure of all root modules
> >   see e.g. o.e.j.i.core.builder.ClasspathJrt.addRequired(String, Set<String>)
Comment 19 Stephan Herrmann CLA 2017-11-21 04:54:08 EST
(In reply to Stephan Herrmann from comment #17)
> * in javac limit-modules can hide user modules on the modulepath, too
> * in ecj limit-modules only affects system modules
> => JEP 261 does not restrict this option to system modules.
> => Filtering individual modules from a directory holding many compiled
> modules _could_ be useful.
> => Should be fixed but IMHO this has secondary importance.

Can be easily fixed in org.eclipse.jdt.internal.compiler.batch.ClasspathLocation.getModuleNames(Collection<String>)
Comment 20 Stephan Herrmann CLA 2017-11-21 05:01:16 EST
During debugging I see that org.eclipse.jdt.internal.compiler.batch.ClasspathJrt.getModuleNames(Collection<String>) may produce the same module name more than once.

Directly accessing ModulesCache.values() (where ModulesCache is static) looks wrong to me, should most like use ModulesCache.get(this.file.getPath()), no?

In normal operation this may only be a performance issue (assuming that a single batch compilation will never access more than one JRT location), but looks wrong anyway.

Well, even batch compilation could be called several times within the same Java process (e.g., from ant?) in which case necessary isolation between invocations would be broken.
Comment 21 Jay Arthanareeswaran CLA 2017-11-21 05:04:16 EST
(In reply to Stephan Herrmann from comment #18)
> (In reply to Stephan Herrmann from comment #17)
> > More differences regarding --limit-modules:
> > 
> > * javac implicitly adds java.base
> > * ecj with limit-modules lacking java.base gives:
> >     The type java.lang.Object cannot be resolved. It is indirectly
> > referenced from required .class files
> > => This could be seen as lack of computing the transitive closure, because
> > any --limit-modules X should pull in dependencies of X, which always
> > contains java.base

This should be done for non system modules as well, right? In which case, I will add the algorithm in ClasspathLocation and use it in the sub types.
Comment 22 Stephan Herrmann CLA 2017-11-21 05:11:21 EST
(In reply to Stephan Herrmann from comment #20)
> During debugging I see that
> org.eclipse.jdt.internal.compiler.batch.ClasspathJrt.
> getModuleNames(Collection<String>) may produce the same module name more
> than once.

FYI, duplication arises because of these paths of initialization:

ClasspathJrt.loadModules() line: 190	
ClasspathJrt.initialize() line: 182	
FileSystem.getClasspath(String, String, boolean, AccessRuleSet, String, Map<String,String>) line: 268	
FileSystem.getClasspath(String, String, AccessRuleSet, Map<String,String>) line: 224	
FileSystem.<init>(String[], String[], String) line: 178	
RegressionTestSetup.setUp() line: 31	

Uses file /home/java/jdk-9.0.1/lib/jrt-fs.jar


ClasspathJrt.loadModules() line: 190	
ClasspathJrt.initialize() line: 182	
FileSystem.<init>(Classpath[], String[], boolean, Set<String>) line: 201	
Main.getLibraryAccess() line: 3446	
Main.performCompilation() line: 4630	
Main.compile(String[]) line: 1771	
ModuleCompilationTests(AbstractBatchCompilerTest).invokeCompiler(PrintWriter, PrintWriter, Object, AbstractBatchCompilerTest$TestCompilationProgress) line: 662	

Uses file /home/java/jdk-9.0.1

Is this difference intended in some way?


Interstingly, the first initialization isn't even used, search for references to 
 - org.eclipse.jdt.core.tests.compiler.regression.RegressionTestSetup.javaClassLib
 - org.eclipse.jdt.core.tests.compiler.regression.AbstractRegressionTest.javaClassLib

Or better: just remove both fields incl. their initialization :)
Comment 23 Stephan Herrmann CLA 2017-11-21 05:13:39 EST
(In reply to Jay Arthanareeswaran from comment #21)
> (In reply to Stephan Herrmann from comment #18)
> > (In reply to Stephan Herrmann from comment #17)
> > > More differences regarding --limit-modules:
> > > 
> > > * javac implicitly adds java.base
> > > * ecj with limit-modules lacking java.base gives:
> > >     The type java.lang.Object cannot be resolved. It is indirectly
> > > referenced from required .class files
> > > => This could be seen as lack of computing the transitive closure, because
> > > any --limit-modules X should pull in dependencies of X, which always
> > > contains java.base
> 
> This should be done for non system modules as well, right? In which case, I
> will add the algorithm in ClasspathLocation and use it in the sub types.

For the transitive closure: yes.

(emphasizing that part because the JEP 261 algo also has that first phase were default system modules for compilation of the unnamed module are computed).
Comment 24 Stephan Herrmann CLA 2017-11-21 05:17:15 EST
Nitpick: field FileSystem.limitedModules is not used outside constructors, so it can be safely removed.
Comment 25 Stephan Herrmann CLA 2017-11-21 05:24:23 EST
(In reply to Stephan Herrmann from comment #24)
> Nitpick: field FileSystem.limitedModules is not used outside constructors,
> so it can be safely removed.

... unless FileSystem.scanForModules(Parser) should actually apply limit-modules filtering, too. Mmmh... (not critical, since scanForModules() is for test use, only).
Comment 26 Jay Arthanareeswaran CLA 2017-11-21 11:54:56 EST
(In reply to Stephan Herrmann from comment #25)
> (In reply to Stephan Herrmann from comment #24)
> > Nitpick: field FileSystem.limitedModules is not used outside constructors,
> > so it can be safely removed.
> 
> ... unless FileSystem.scanForModules(Parser) should actually apply
> limit-modules filtering, too. Mmmh... (not critical, since scanForModules()
> is for test use, only).

I have taken care of the comments except this one and the duplicated classpath entries from test framework. I have taken care of the cache in ClasspathJrt.

Please take another look. TIA!
Comment 27 Stephan Herrmann CLA 2017-11-21 13:09:22 EST
I dropped some more detail comments into gerrit.

Of those, only the one in ClasspathJrt looks like a bug to me. I'm giving my +1 for 4.7.2RC3 on the condition that this one issue is either fixed or explained why not a problem :)
Comment 28 Jay Arthanareeswaran CLA 2017-11-21 20:37:45 EST
(In reply to Stephan Herrmann from comment #27)
> I dropped some more detail comments into gerrit.
> 
> Of those, only the one in ClasspathJrt looks like a bug to me. I'm giving my
> +1 for 4.7.2RC3 on the condition that this one issue is either fixed or
> explained why not a problem :)

I fixed that one and the one in FileSystem partially (I do the double computation only when limitModules is specified) and released via:

http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?h=R4_7_maintenance&id=ae9381791c949494b78b3c4ae5c79aaab8d20f3d

and 

http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?h=R4_7_maintenance&id=a4575294051fce35b1d746f00ea3f10165ea0784
Comment 29 Stephan Herrmann CLA 2017-11-22 06:28:20 EST
(In reply to Jay Arthanareeswaran from comment #28)
> (In reply to Stephan Herrmann from comment #27)
> > I dropped some more detail comments into gerrit.
> > 
> > Of those, only the one in ClasspathJrt looks like a bug to me. I'm giving my
> > +1 for 4.7.2RC3 on the condition that this one issue is either fixed or
> > explained why not a problem :)
> 
> I fixed that one and the one in FileSystem partially (I do the double
> computation only when limitModules is specified) and released via:
> 
> http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/
> ?h=R4_7_maintenance&id=ae9381791c949494b78b3c4ae5c79aaab8d20f3d
> 
> and 
> 
> http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/
> ?h=R4_7_maintenance&id=a4575294051fce35b1d746f00ea3f10165ea0784

I glimpsed over that latter commit, and I'm not sure we're on the same page:
- condition should be: are we compiling the unnamed module
- action should be: restrict system modules as implemented in allModules(..)

Conversely: transitive closure should (to the best of my knowledge) happen always.

Is this, what the commit does?
Comment 30 Jay Arthanareeswaran CLA 2017-11-22 11:28:08 EST
(In reply to Stephan Herrmann from comment #29)
> Is this, what the commit does?

Stephan,

Yes, there's some confusion. In comment #23, you mentioned you were particular only about the suggestion on ClasspathJrt and I mistook the suggestions on ClasspathJrt in gerrit as that. I should have figured, though. I will raise a new bug for this.

I am also confused by this in JEP 261:

"The transitive closure computed for the interpretation of the --limit-modules option is a temporary result, used only to compute the limited set of observable modules. The resolver will be invoked again in order to compute the actual module graph."
Comment 31 Jay Arthanareeswaran CLA 2017-11-22 11:42:45 EST
(In reply to Jay Arthanareeswaran from comment #30)
> I will raise a new bug for this.

We have the bug 526110 anyway. I am closing this report.

The fix for master is here:

http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=fc84571f988be37d385969a14cd975993468af5d
Comment 32 Stephan Herrmann CLA 2017-11-22 18:18:12 EST
(In reply to Jay Arthanareeswaran from comment #30)
> (In reply to Stephan Herrmann from comment #29)
> > Is this, what the commit does?
> 
> Stephan,
> 
> Yes, there's some confusion. In comment #23, you mentioned you were
> particular only about the suggestion on ClasspathJrt and I mistook the
> suggestions on ClasspathJrt in gerrit as that. I should have figured,
> though. I will raise a new bug for this.

My bad, comment 27 should've said "ClasspathLocation" :(



> I am also confused by this in JEP 261:
> 
> "The transitive closure computed for the interpretation of the
> --limit-modules option is a temporary result, used only to compute the
> limited set of observable modules. The resolver will be invoked again in
> order to compute the actual module graph."

yea, that's a bit strange. Perhaps the point is that after throwing only the limited modules into the pot, we then add the current module to the stew and stir once again - meaning: starting from the current module we will then compute *its* transitive closure from the universe of limited modules (so probably dropping more modules from the module graph)?
Hope I'm not adding still more confusion :-/
Comment 33 Sasikanth Bharadwaj CLA 2017-11-23 04:23:04 EST
Verified for 4.7.2 using M20171122-1700 build
Comment 34 Stephan Herrmann CLA 2017-11-25 07:32:03 EST
(In reply to Jay Arthanareeswaran from comment #28)
> (In reply to Stephan Herrmann from comment #27)
> > I dropped some more detail comments into gerrit.
> > 
> > Of those, only the one in ClasspathJrt looks like a bug to me. I'm giving my
> > +1 for 4.7.2RC3 on the condition that this one issue is either fixed or
> > explained why not a problem :)
> 
> I fixed that one and the one in FileSystem partially (I do the double
> computation only when limitModules is specified) and released via:
> 
> http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/
> ?h=R4_7_maintenance&id=ae9381791c949494b78b3c4ae5c79aaab8d20f3d

This commit contains the tests for bug 500170 without containing the fix.

Official builds still don't notice because this simply skip all tests in this suite.

Running locally on Java 9 shows two failures.

If JDT/Core will contribute for RC4 these tests should be removed.
Or did you plan to backport also bug 500170?
Comment 35 Stephan Herrmann CLA 2017-11-25 08:01:24 EST
(In reply to Stephan Herrmann from comment #34)
> Official builds still don't notice because this simply skip all tests in
> this suite.

see bug 527750
Comment 36 Jay Arthanareeswaran CLA 2017-11-27 06:54:19 EST
(In reply to Stephan Herrmann from comment #34)
> If JDT/Core will contribute for RC4 these tests should be removed.

Noted.

> Or did you plan to backport also bug 500170?

Would have been nice to have that in 4.7.2. But we will consider for 4.7.3 now.
Comment 37 Manoj N Palat CLA 2017-12-05 23:41:46 EST
Verified for Eclipse Photon 4.8 M4 with Build id: I20171205-0800
Comment 38 Manoj N Palat CLA 2018-01-08 21:12:22 EST
@Jay: Local run of ModuleCompilationTests on J9 gets me around 10 failures for the tests of this bug - could you please check this out?
Comment 39 Jay Arthanareeswaran CLA 2018-01-11 08:14:05 EST
(In reply to Manoj Palat from comment #38)
> @Jay: Local run of ModuleCompilationTests on J9 gets me around 10 failures
> for the tests of this bug - could you please check this out?

Manoj, I don't see any failures on HEAD. Which version of Jre do you use?
Comment 40 Stephan Herrmann CLA 2018-02-15 16:35:59 EST
I still see this:

(In reply to Stephan Herrmann from comment #34)
> (In reply to Jay Arthanareeswaran from comment #28)
> > http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/
> > ?h=R4_7_maintenance&id=ae9381791c949494b78b3c4ae5c79aaab8d20f3d
> 
> This commit contains the tests for bug 500170 without containing the fix.
> 
> Official builds still don't notice because this simply skip all tests in
> this suite.
> 
> Running locally on Java 9 shows two failures.
> 
> If JDT/Core will contribute for RC4 these tests should be removed.
> Or did you plan to backport also bug 500170?

See also bug 500170 comment 6.

Note, that bug 527750 was fixed only for master, so Java 9 tests are not run by gerrit.