Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 525831 - Access rules not working when running with Java 9 JRE
Summary: Access rules not working when running with Java 9 JRE
Status: RESOLVED WORKSFORME
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Debug (show other bugs)
Version: 4.7.1   Edit
Hardware: All All
: P3 critical (vote)
Target Milestone: 4.8 M7   Edit
Assignee: Sarika Sinha CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-10-10 13:04 EDT by Eric Milles CLA
Modified: 2018-04-24 11:24 EDT (History)
7 users (show)

See Also:


Attachments
JavaSE-9.profile (6.61 KB, application/octet-stream)
2018-03-28 15:13 EDT, Sarika Sinha CLA
no flags Details
JavaSE-10.profile (6.59 KB, application/octet-stream)
2018-03-28 15:15 EDT, Sarika Sinha CLA
no flags Details
Java SE profile using oracle doc (7.00 KB, application/octet-stream)
2018-04-16 02:36 EDT, Sarika Sinha CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Eric Milles CLA 2017-10-10 13:04:50 EDT
I've been experimenting with Eclipse 4.7.1a release candidates and have found one difference in terms of project classpath.  The build access restrictions are not enforced for classes loaded from Java 9 modules.

Example:

  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
    <accessrules>
      <accessrule kind="nonaccessible" pattern="groovy/beans/**" />
    </accessrules>
  </classpathentry>

When a project with this classpath entry is compiled using Eclipse running under Java 9, the reference to java.beans.BeanInfo is no longer flagged.

I traced this to org.eclipse.jdt.internal.core.builder.ClasspathJrt.findClass:

public NameEnvironmentAnswer findClass(String binaryFileName, String qualifiedPackageName, String moduleName, String qualifiedBinaryFileName, boolean asBinaryOnly) {
	...
		IBinaryType reader = ClassFileReader.readFromModule(new File(this.zipFilename), moduleName, qualifiedBinaryFileName);
		if (reader != null) {
			if (this.externalAnnotationPath != null) {
				String fileNameWithoutExtension = qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - SuffixConstants.SUFFIX_CLASS.length);
				try {
					if (this.annotationZipFile == null) {
						this.annotationZipFile = ExternalAnnotationDecorator.getAnnotationZipFile(this.externalAnnotationPath, null);
					}
					reader = ExternalAnnotationDecorator.create(reader, this.externalAnnotationPath, fileNameWithoutExtension, this.annotationZipFile);
				} catch (IOException e) {
					// don't let error on annotations fail class reading
				}
			}
			return new NameEnvironmentAnswer(reader, null, reader.getModule()); // AccessRestriction always null!
Comment 1 Eric Milles CLA 2017-10-10 13:06:48 EDT
Sorry, the restriction is supposed to be on "java/beans/**" not "groovy/beans/**" in the example.
Comment 2 Stephan Herrmann CLA 2017-10-10 15:12:11 EDT
Mhh, unlike ClasspathJar, ClasspathJrt doesn't even have #accessRuleSet

@Jay, when you created ClasspathJrt, did you have reasons to omit the concept of access rules (perhaps assuming that jigsaw will take care of this), or is this an oversight?
Comment 3 Jay Arthanareeswaran CLA 2017-10-11 00:21:24 EDT
(In reply to Stephan Herrmann from comment #2)
> Mhh, unlike ClasspathJar, ClasspathJrt doesn't even have #accessRuleSet
> 
> @Jay, when you created ClasspathJrt, did you have reasons to omit the
> concept of access rules (perhaps assuming that jigsaw will take care of
> this), or is this an oversight?

I wasn't sure how this will play with the module related restrictions that the Jigsaw introduces. But I did overlook the fact that it might still be used in the same way in a non modular set up.
Comment 4 Jay Arthanareeswaran CLA 2017-11-15 07:11:34 EST
I don't see this going in 4.7.2. Need to think through the solution. Perhaps for 4.7.3
Comment 5 Dani Megert CLA 2018-03-27 08:49:07 EDT
AFAIK the API packages come from the EE profile and are provided by JDT Launching.

Currently when going to a project's Java Build Path page, no restrictions are listed and of course later also not applied.

Example:

package c;

import com.oracle.net.Sdp;

public class X {
	
	public static void main(String[] args) {
		System.out.println(Sdp.class);
	}
}

Should give errors (which it does for 1.8) but does not.

This needs to be fixed. Maybe JDT Launching needs to define the profiles which are no longer provided by org.eclipse.osgi.
Comment 6 Stephan Herrmann CLA 2018-03-27 09:19:29 EDT
How does this relate to bug 531642?

I thought the current bug is about explicit user-defined access rules, not those intrinsic to the JRE?
Comment 7 Jay Arthanareeswaran CLA 2018-03-27 11:31:31 EDT
Clearly, I didn't see this one even though I was the assignee. Looks like comment #0 is same as bug 528467, which has already been fixed.

Eric, can you try a recent build and see if you have what you wanted.

Comment #5 is something we should re-look in the context of modules. Now that we have the (alternate) module restrictions in place, we don't need the old restrictions. Once a module-info is added to the project, things start working very well. The usage of com.oracle.net.Sdp is flagged, but allowed when the module "requires" oracle.net.

So, all good then?
Comment 8 Eric Milles CLA 2018-03-27 13:48:43 EDT
This has been working properly in Photon for a couple milestones now.  It is still not fixed in Oxygen.3a (RC1).  Not sure if you are targeting a fix for Oxygen.
Comment 9 Dani Megert CLA 2018-03-28 04:32:29 EDT
(In reply to Jay Arthanareeswaran from comment #7)
> Clearly, I didn't see this one even though I was the assignee. Looks like
> comment #0 is same as bug 528467, which has already been fixed.
> 
> Eric, can you try a recent build and see if you have what you wanted.
> 
> Comment #5 is something we should re-look in the context of modules. Now
> that we have the (alternate) module restrictions in place, we don't need the
> old restrictions. Once a module-info is added to the project, things start
> working very well. The usage of com.oracle.net.Sdp is flagged, but allowed
> when the module "requires" oracle.net.
> 
> So, all good then?

No, not good. I can use Java 9 or 10 with an old/non-modular project (with 9 or 10 as EE/compliance) that knows nothing about modules and might not want to be converted.
Comment 10 Sarika Sinha CLA 2018-03-28 06:58:02 EDT
Access rules retrieval -
1. For non modular projects, the default system packages can be provided by launching ( either by hard coding, making profile or update in osgi) and jdt core can just use it for compilation.
2. But for modular projects, there can be mix and match. Launching will provide the default access rules but jdt core uses the access rules set from java build path page and ignores the default access rule. So it requires some change from jdt core also to make this case work.
 
Different combinations of compliance/ build path and results -
1. If the project has 1.8/9/10 as compliance and jre container as 1.8 ( 1.8 may be bound to 9 or 10 in Installed JREs), it still flags the error.
2. Only if the jre container is changed to 9 or 10. It will not flag the error.


Do we want to change the JDT Core compilation strategy for 4.7.3a?
My suggestion is to continue with current state for 4.7.3a and fix properly for 4.8 M7.
Comment 11 Sarika Sinha CLA 2018-03-28 07:27:40 EDT
In the mean while I am trying to create the profiles for osgi for 9 and 10 and try out access rules.
Comment 12 Dani Megert CLA 2018-03-28 08:40:28 EDT
(In reply to Sarika Sinha from comment #10)
> Do we want to change the JDT Core compilation strategy for 4.7.3a?

No.
Comment 13 Stephan Herrmann CLA 2018-03-28 10:41:47 EDT
For non-modular projects the default system modules are defined by JEP 261.  From there the set of available packages is defined in the individual modules. When JDT/Core is used to find dependencies via IPackageFragmentRoot etc all this should already be taken care of.

I really think profiles for 9+ are the wrong approach. Different JDKs may have different content, which cannot be modeled by a static profile.

Explicit, user-defined access rules have been brought back via this bug.
Comment 14 Stephan Herrmann CLA 2018-03-28 12:43:24 EDT
(In reply to Stephan Herrmann from comment #13)
> Explicit, user-defined access rules have been brought back via this bug.

Bug 528467 to be precise.

@Dani, I don't really see anything needing a fix here.
Comment 15 Sarika Sinha CLA 2018-03-28 15:13:26 EDT
Created attachment 273348 [details]
JavaSE-9.profile
Comment 16 Sarika Sinha CLA 2018-03-28 15:15:45 EDT
Created attachment 273350 [details]
JavaSE-10.profile

I have attached the complete profile for JavaSE-9 and JavaSE-10

The list is totally different from 1.8. And We have oracle.net in the list so adding "Sdp.class" actually will not be flagged with Java 9 or 10 any more.
Comment 17 Sarika Sinha CLA 2018-03-29 02:34:41 EDT
Another set of findings -
1. Adding Explicit access rules work fine with java 9 compliance modular or non modular projects in flagging the compilation error in java source files. But it does not flag error in module-info.java having requires. Adding --limit-modules, flag the error in module-info and java source files.

2. Patterns like java.beans now has to be added through access rules as they are part of java.desktop which is implicitly added module.

3. The list of packages for Java 9 and 10 appears to be the full list, so there is not much meaning of Default access rules for the current version of 9 and 10. (May be it can change in the future drops but not very likely as they have --limit-modules).
Comment 18 Dani Megert CLA 2018-03-29 06:10:01 EDT
(In reply to Sarika Sinha from comment #17)
> 3. The list of packages for Java 9 and 10 appears to be the full list

I'm not sure this is correct. At least in 1.8 and before the com.sun/oracle.* packages were not listed there. And from that we computed our access rules in order to support the Eclipse access rules feature. The user can set that to warning or ignore. At any rate even with the errors shown in the CU from comment 5, you can actually run the example with 1.8. So, I would expect that if that list would have been computed for 1.8 from runtime info, it might also have had com.sun/oracle. Unfortunately I don't know who compiled the list for 1.8 and below.

Tom, any idea?
Comment 19 Stephan Herrmann CLA 2018-03-29 08:26:21 EDT
OK, one thing is missing for sure: deprecation of modules (since bug 515388) doesn't seem to be detected when accessed from an unnamed module.

If it were, then the use of com.oracle.net.Sdp would be flagged because module oracle.net is @Deprecated(since="9", forRemoval=true)

Additionally, even for unnamed modules, we seem to have issues with deprecation in HEAD.

My guess is that JEP 261 together with deprecation of modules completely replaces any previous strategies that were represented by those profiles.
Comment 20 Stephan Herrmann CLA 2018-03-29 08:48:39 EDT
module-info.class may additionally contain a ModulePackages attribute, but this is (a) optional, (b) may or may not contain "private" packages. Ergo this attribute cannot be relied on for validating access to classes in the module.

See https://docs.oracle.com/javase/specs/jvms/se10/html/jvms-4.html#jvms-4.7.26
Comment 21 Sarika Sinha CLA 2018-03-29 08:52:36 EDT
// Compiled from Sdp.java (version 10 : 54.0, super bit, deprecated)
@java.lang.Deprecated(since="10",
  forRemoval=true)
Comment 22 Stephan Herrmann CLA 2018-03-29 09:11:50 EDT
(In reply to Stephan Herrmann from comment #19)
> If it were, then the use of com.oracle.net.Sdp would be flagged because
> module oracle.net is @Deprecated(since="9", forRemoval=true)

Sorry, here I was fooled by bug 532733, the deprecation exists on java.se.ee, but not on oracle.net.
Comment 23 Thomas Watson CLA 2018-03-29 10:21:21 EDT
(In reply to Dani Megert from comment #18)
> (In reply to Sarika Sinha from comment #17)
> > 3. The list of packages for Java 9 and 10 appears to be the full list
> 
> I'm not sure this is correct. At least in 1.8 and before the
> com.sun/oracle.* packages were not listed there. And from that we computed
> our access rules in order to support the Eclipse access rules feature. The
> user can set that to warning or ignore. At any rate even with the errors
> shown in the CU from comment 5, you can actually run the example with 1.8.
> So, I would expect that if that list would have been computed for 1.8 from
> runtime info, it might also have had com.sun/oracle. Unfortunately I don't
> know who compiled the list for 1.8 and below.
> 
> Tom, any idea?

I compiled that list from the publicly available Java doc for the Java SE versions.  They do not javadoc com.sun/oracle packages there.
Comment 24 Sarika Sinha CLA 2018-03-30 02:58:23 EDT
Ok, So I see that we can still do that.
https://docs.oracle.com/javase/9/docs/api/overview-summary.html
https://docs.oracle.com/javase/10/docs/api/overview-summary.html

Will have to go through each Java SE module and find the list of packages.
We can add Java FX package list as well.

May be for non modular projects we could use this, and for modular projects use the --limit-modules ?
Comment 25 Dani Megert CLA 2018-04-06 08:42:59 EDT
(In reply to Sarika Sinha from comment #24)
> Ok, So I see that we can still do that.
> https://docs.oracle.com/javase/9/docs/api/overview-summary.html
> https://docs.oracle.com/javase/10/docs/api/overview-summary.html
> 
> Will have to go through each Java SE module and find the list of packages.
> We can add Java FX package list as well.
> 
> May be for non modular projects we could use this

Yes.


> and for modular projects use the --limit-modules ?

Let's leave that to another bug report. With modular projecets our access restriction stuff for the JDK/JRE is not relevant anymore as Stephan already pointed out.
Comment 26 Sarika Sinha CLA 2018-04-16 02:36:17 EDT
Created attachment 273616 [details]
Java SE profile using oracle doc

I have compiled the JavaSE-9.profile for Java SE only.

This does not include jdk, javafx and other module right now.

I see we have missing org.w3c.dom.* now in JavaSE 9 profile. A part of it is present in JDK profile. Mosyly JDK profile has jdk.* and org.sun.com.*
Comment 27 Dani Megert CLA 2018-04-24 11:23:47 EDT
With Java 9 onward the --release option does that trick.