Bug 482318 - [Java9] Illegal Access Exception with SWT_AWT on JDK9+Jigsaw
Summary: [Java9] Illegal Access Exception with SWT_AWT on JDK9+Jigsaw
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 4.6   Edit
Hardware: PC Windows NT
: P3 normal (vote)
Target Milestone: 4.7 M2   Edit
Assignee: Lakshmi P Shanmugam CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 492087 (view as bug list)
Depends on: 499545
Blocks: 492087
  Show dependency tree
 
Reported: 2015-11-16 14:34 EST by Wayne Beaton CLA
Modified: 2019-06-26 07:17 EDT (History)
13 users (show)

See Also:


Attachments
patch (7.47 KB, patch)
2016-05-20 09:21 EDT, Lakshmi P Shanmugam CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Wayne Beaton CLA 2015-11-16 14:34:18 EST
I'm using the Neon M2 drop of the SDK on Windows 8 (64-bit) along with the most recent drop (b86) of the JDK 1.9 EA with Jigsaw.

The jdeps tool reported a dependency on internal API within the SWT_AWT code, so I tested/confirmed using snippet135. Here's the top of the stack trace:

Exception in thread "main" org.eclipse.swt.SWTError: Not implemented (java.lang.IllegalAccessException: class org.eclipse.swt.awt.SWT_AWT$1 cannot access class sun.awt.windows.WEmbeddedFrame (in module java.desktop) because module java.desktop does not export package sun.awt.windows to <unnamed module @4680db8c>)
	at org.eclipse.swt.SWT.error(SWT.java:4529)
	at org.eclipse.swt.SWT.error(SWT.java:4418)
	at org.eclipse.swt.awt.SWT_AWT.new_Frame(SWT_AWT.java:225)
	at org.eclipse.swt.snippets.Snippet135.main(Snippet135.java:155)
Caused by: java.lang.IllegalAccessException: class org.eclipse.swt.awt.SWT_AWT$1 cannot access class sun.awt.windows.WEmbeddedFrame (in module java.desktop) because module java.desktop does not export package sun.awt.windows to <unnamed module @4680db8c>
	at sun.reflect.Reflection.throwIllegalAccessException(java.base@9.0/Reflection.java:455)
	at sun.reflect.Reflection.ensureMemberAccess(java.base@9.0/Reflection.java:130)
	at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(java.base@9.0/AccessibleObject.java:370)
	at java.lang.reflect.AccessibleObject.checkAccess(java.base@9.0/AccessibleObject.java:362)
	at java.lang.reflect.Constructor.newInstance(java.base@9.0/Constructor.java:435)
	at org.eclipse.swt.awt.SWT_AWT$1.run(SWT_AWT.java:172)

For completeness:

C:\Users\Wayne\jigsaw-jdk-bin-windows-x64\jdk1.9.0\bin>java -version
java version "1.9.0-ea"
Java(TM) SE Runtime Environment (build 1.9.0-ea-jigsaw-nightly-h3660-20151022-b86)
Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-jigsaw-nightly-h3660-20151022-b86, mixed mode)
Comment 1 Wayne Beaton CLA 2015-11-16 14:42:03 EST
I'm also seeing it on Fedora 22 (GTK3).

Exception in thread "main" org.eclipse.swt.SWTError: Not implemented (java.lang.IllegalAccessException: class org.eclipse.swt.awt.SWT_AWT cannot access class sun.awt.X11.XEmbeddedFrame (in module java.desktop) because module java.desktop does not export package sun.awt.X11 to <unnamed module @309e345f>)
	at org.eclipse.swt.SWT.error(SWT.java:4517)
	at org.eclipse.swt.SWT.error(SWT.java:4406)
	at org.eclipse.swt.awt.SWT_AWT.new_Frame(SWT_AWT.java:179)
	at org.eclipse.swt.snippets.Snippet135.main(Snippet135.java:155)
Caused by: java.lang.IllegalAccessException: class org.eclipse.swt.awt.SWT_AWT cannot access class sun.awt.X11.XEmbeddedFrame (in module java.desktop) because module java.desktop does not export package sun.awt.X11 to <unnamed module @309e345f>
	at sun.reflect.Reflection.throwIllegalAccessException(java.base@9.0/Reflection.java:455)
	at sun.reflect.Reflection.ensureMemberAccess(java.base@9.0/Reflection.java:130)
	at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(java.base@9.0/AccessibleObject.java:370)
	at java.lang.reflect.AccessibleObject.checkAccess(java.base@9.0/AccessibleObject.java:362)
	at java.lang.reflect.Constructor.newInstance(java.base@9.0/Constructor.java:435)
	at org.eclipse.swt.awt.SWT_AWT.new_Frame(SWT_AWT.java:177)
Comment 2 Lakshmi P Shanmugam CLA 2015-11-24 04:10:20 EST
The SWT_AWT bridge code requires access to 
sun.awt.windows.WEmbeddedFrame on Windows, 
sun.awt.X11.XEmbeddedFrame on GTK and
sun.lwawt.macosx.CViewEmbeddedFrame on Mac-Cocoa

According to the JEP 260 (http://openjdk.java.net/jeps/260), the classes in sun.* packages are internal APIs and will not be accessible in Java 9. These have not been identified as critical APIs in the JEP and no exception has been provided for them.
I think these classes didn't show up on the search as we are calling them through reflection. Running jdeps on swt.jar doesn't catch these internal API usages.

Dani, can you please advice on what to do? Should we request for marking them as critical APIs or provide replacement APIs?
Comment 3 Dani Megert CLA 2015-12-01 05:03:57 EST
(In reply to Lakshmi Shanmugam from comment #2)
> The SWT_AWT bridge code requires access to 
> sun.awt.windows.WEmbeddedFrame on Windows, 
> sun.awt.X11.XEmbeddedFrame on GTK and
> sun.lwawt.macosx.CViewEmbeddedFrame on Mac-Cocoa
> 
> According to the JEP 260 (http://openjdk.java.net/jeps/260), the classes in
> sun.* packages are internal APIs and will not be accessible in Java 9. These
> have not been identified as critical APIs in the JEP and no exception has
> been provided for them.
> I think these classes didn't show up on the search as we are calling them
> through reflection. Running jdeps on swt.jar doesn't catch these internal
> API usages.
> 
> Dani, can you please advice on what to do? Should we request for marking
> them as critical APIs or provide replacement APIs?

You mean *use* official APIs?


You also have to go through the code and check whether there are other places where reflection is used.
Comment 4 Dani Megert CLA 2015-12-01 05:44:05 EST
(In reply to Dani Megert from comment #3)
> (In reply to Lakshmi Shanmugam from comment #2)
> > The SWT_AWT bridge code requires access to 
> > sun.awt.windows.WEmbeddedFrame on Windows, 
> > sun.awt.X11.XEmbeddedFrame on GTK and
> > sun.lwawt.macosx.CViewEmbeddedFrame on Mac-Cocoa
> > 
> > According to the JEP 260 (http://openjdk.java.net/jeps/260), the classes in
> > sun.* packages are internal APIs and will not be accessible in Java 9. These
> > have not been identified as critical APIs in the JEP and no exception has
> > been provided for them.
> > I think these classes didn't show up on the search as we are calling them
> > through reflection. Running jdeps on swt.jar doesn't catch these internal
> > API usages.
> > 
> > Dani, can you please advice on what to do? Should we request for marking
> > them as critical APIs or provide replacement APIs?
> 
> You mean *use* official APIs?

If there are no such APIs yet, then we have to ask them to provide this and in the meantime put them on the critical API list.
Comment 5 Andrey Loskutov CLA 2016-01-25 04:00:17 EST
See https://bugs.openjdk.java.net/browse/JDK-8148109
Comment 6 Sergey Bylokhov CLA 2016-04-10 17:46:14 EDT
There is a workaround.
The jigsaw bounds checking does not work inside a jni, since the swt library already have a libswt-awt native library it is possible to wrap the calls to sun.** classes via jni. I proved this on OSX(where I wrapped the calls to CViewEmbeddedFrame.init/synthesizeWindowActivation/validateWithBounds). Note that this solution will work in case of jdk7/8/9.

Please confirm that you will be able to resolve this error "something does not export".
Comment 7 Lakshmi P Shanmugam CLA 2016-04-11 07:40:49 EDT
(In reply to Sergey Bylokhov from comment #6)

> Please confirm that you will be able to resolve this error "something does
> not export".
Sorry I didn't follow, can you please explain what has to be confirmed?
Comment 8 Sergey Bylokhov CLA 2016-04-11 12:04:11 EDT
In JDK 9 reflection is not able to access the internal classes(which were not exported). I suggest to change the code inside an SWT libary, and use the native code , instead of access via Reflection"java->native->EmbeddedFrame(and other sun.awt clases)".

I need a confirmation that it will work for you, after that I will close JDK-8148109 which was mentioned before.

The code will look like this:

Java:

==============================

+ static native final void validateWithBounds(Frame frame, int x, int y, int w, int h);

==============================

+                        validateWithBounds(frame, clientArea.x,clientArea.y,
+                                clientArea.width,clientArea.height);
+//                        Method method = frame.getClass().getMethod(
+//                                "validateWithBounds", int.class, int.class,
+//                                int.class, int.class);
+//                        if (method != null)
+//                            method.invoke(frame, Integer.valueOf(clientArea.x),
+//                                    Integer.valueOf(clientArea.y),
+//                                    Integer.valueOf(clientArea.width),
+//                                    Integer.valueOf(clientArea.height));

==============================

Native:

+JNIEXPORT void JNICALL Java_org_eclipse_swt_awt_SWT_1AWT_validateWithBounds
+(JNIEnv *env, jclass that, jobject frame, jint x,jint y,jint w,jint h)
+{
+    jclass cls = (*env)->FindClass(env, "sun/lwawt/macosx/CViewEmbeddedFrame");
+    if (NULL == cls) return;
+    jmethodID midInit = (*env)->GetMethodID(env, cls, "validateWithBounds", "(IIII)V");
+    (*env)->CallVoidMethod(env, frame, midInit, x,y,w,h);
+}
Comment 9 Lakshmi P Shanmugam CLA 2016-04-15 07:33:04 EDT
(In reply to Sergey Bylokhov from comment #8)
I'll look into the proposed solution and get back on this in a week's time.
Comment 10 Sergey Bylokhov CLA 2016-05-06 13:22:59 EDT
(In reply to Lakshmi Shanmugam from comment #9)
> I'll look into the proposed solution and get back on this in a week's time.

Hi, Do you have any update?
Comment 11 Lakshmi P Shanmugam CLA 2016-05-19 04:34:51 EDT
(In reply to Sergey Bylokhov from comment #10)
> (In reply to Lakshmi Shanmugam from comment #9)
> > I'll look into the proposed solution and get back on this in a week's time.
> 
> Hi, Do you have any update?

Hi, sorry for the delayed response. We are in the Eclipse 4.6 endgame and I was held up with other last minute work for the release. I've started working on this. I should be able to provide an update in a day or two.
Comment 12 Lakshmi P Shanmugam CLA 2016-05-20 09:21:55 EDT
Created attachment 261894 [details]
patch

I tried the changes suggested in comment 8 and ran couple of example Snippets 154, 155 on Java 9 build (jdk-9-ea+112_osx-x64).
There were no errors or exceptions, but the AWT frame doesn't appear. I debugged the code and confirmed that I get a Frame object from initFrame. But, not sure if something else is failing here.
I've attached the changes here for reference. The same code runs fine with Java 8.
I'm running Java 9 on OSX 10.11.
Comment 13 Sergey Bylokhov CLA 2016-05-20 13:46:46 EDT
> I tried the changes suggested in comment 8 and ran couple of example
> Snippets 154, 155 on Java 9 build (jdk-9-ea+112_osx-x64).
> There were no errors or exceptions, but the AWT frame doesn't appear. I
> debugged the code and confirmed that I get a Frame object from initFrame.
> But, not sure if something else is failing here.
> I've attached the changes here for reference. The same code runs fine with
> Java 8.
> I'm running Java 9 on OSX 10.11.

There was a bug which was fixed in jdk9b117:
https://bugs.openjdk.java.net/browse/JDK-8154088

You need to use >= jdk9b177
Comment 14 Sergey Bylokhov CLA 2016-05-29 13:59:43 EDT
Note that it is not necessary to move all methods to the native, only inaccessible methods. For example it is not necessary to move addNotify(), dispatchEvent().

Also FYI, I'll provide a set of new methods in jawt library which will encapsulate a knowledge about the internal names. And these new methods will be used in your native code:

For example this:
+	jclass cls = (*env)->FindClass(env, "sun/lwawt/macosx/CViewEmbeddedFrame");
+	if (NULL == cls) return NULL;
+	constructor = (*env)->GetMethodID(env, cls, "<init>", "(J)V");
+	object = (*env)->NewObject(env, cls, constructor, handle);

Will be replaced by something like this:
+{
+       awt_CreateEmbeddedComponent(env, handle);
+}

I have a prototype on OSX on top of your patch, but do you have some update for windows and linux?
Comment 15 Lakshmi P Shanmugam CLA 2016-06-06 07:36:18 EDT
(In reply to Sergey Bylokhov from comment #14)

> I have a prototype on OSX on top of your patch, but do you have some update
> for windows and linux?
For linux (Ubuntu 14.04), only the constructor had to be replaced with initFrame native code. I tried it and the change works fine. I'll upload the patch after some code cleanup.
I'll be trying out Windows next.
Comment 16 Eclipse Genie CLA 2016-06-14 02:21:20 EDT
New Gerrit change created: https://git.eclipse.org/r/75211
Comment 17 Lakshmi P Shanmugam CLA 2016-06-14 02:29:41 EDT
The gerrit patch has the required changes for all 3 platforms. I've cleaned up the code that was required only for older versions of java. Tested the patch with jdk9+121 build and it works fine on Mac OSX and Linux-gtk.
I've still not been able to verify the patch on Windows due to some build issues, we are looking into it.
Comment 18 Lakshmi P Shanmugam CLA 2016-06-14 02:47:27 EDT
(In reply to Sergey Bylokhov from comment #14)
> Note that it is not necessary to move all methods to the native, only
> inaccessible methods. For example it is not necessary to move addNotify(),
> dispatchEvent().
I've removed the unnecessary changes for all platforms.

> 
> Also FYI, I'll provide a set of new methods in jawt library which will
> encapsulate a knowledge about the internal names. And these new methods will
> be used in your native code:
> 
> For example this:
> +	jclass cls = (*env)->FindClass(env, "sun/lwawt/macosx/CViewEmbeddedFrame");
> +	if (NULL == cls) return NULL;
> +	constructor = (*env)->GetMethodID(env, cls, "<init>", "(J)V");
> +	object = (*env)->NewObject(env, cls, constructor, handle);
> 
> Will be replaced by something like this:
> +{
> +       awt_CreateEmbeddedComponent(env, handle);
> +}
> 
I had missed this before, the SWT_AWT class has a public String member "embeddedFrameClass" that can set by the user/program. If it is null then the default class name for the platform will be used. 
So, even if the internal names are encapsulated, we still need to use the above mechanism to use the user specified name in the native code.
Comment 19 Lakshmi P Shanmugam CLA 2016-06-20 04:07:00 EDT
The latest gerrit patch works on all 3 platforms with JDK 9.
Comment 20 Sergey Bylokhov CLA 2016-07-26 08:51:48 EDT
Does this patch was released as a beta version or something like that?
Comment 21 Lakshmi P Shanmugam CLA 2016-07-29 05:40:19 EDT
(In reply to Sergey Bylokhov from comment #20)
> Does this patch was released as a beta version or something like that?

The patch is not yet released to the repository. Does the patch work with your Java changes? I plan to put it in the BETA_JAVA9 branch so that it can be tried out in the Y-builds.
Comment 22 Markus Keller CLA 2016-08-05 07:15:23 EDT
The BETA_JAVA9 branches and the Y-build are only meant for adding support for development/compilation of Java 9 code in the IDE.

I-builds for Oxygen are expected to run on Java 8 and Java 9 (notwithstanding the breaking change in JDK9 that requires the addition of "-addmods java.se.ee" to the vmargs).

These changes should go directly into the master branch/I-builds. Guard them with a version check if necessary to make sure they don't break running on Java 8.
Comment 23 Lakshmi P Shanmugam CLA 2016-08-11 02:18:30 EDT
I released the patch to master -> http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=2214fda883b89bb4f8ad39483d2e3f9ae1a89294

This I-build has the patch, please try it out -> http://download.eclipse.org/eclipse/downloads/drops4/I20160809-1300/
Comment 24 Niraj Modi CLA 2016-08-12 03:21:23 EDT
(In reply to Lakshmi Shanmugam from comment #23)
> I released the patch to master ->
> http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/
> ?id=2214fda883b89bb4f8ad39483d2e3f9ae1a89294
> 
> This I-build has the patch, please try it out ->
> http://download.eclipse.org/eclipse/downloads/drops4/I20160809-1300/

Above fix is not working on Windows, reason being a linking error during native compilation, see bug 499545.
Comment 25 Niraj Modi CLA 2016-08-25 03:07:28 EDT
(In reply to Niraj Modi from comment #24)
> (In reply to Lakshmi Shanmugam from comment #23)
> > I released the patch to master ->
> > http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/
> > ?id=2214fda883b89bb4f8ad39483d2e3f9ae1a89294
> > 
> > This I-build has the patch, please try it out ->
> > http://download.eclipse.org/eclipse/downloads/drops4/I20160809-1300/
> 
> Above fix is not working on Windows, reason being a linking error during
> native compilation, see bug 499545.

Fix for bug 499545 has successfully unblocked this issue, so fixes made in comment 23 working now in latest IBuild: I20160824-1429 on Win7.
Comment 26 Alexander Kurtakov CLA 2017-03-16 09:31:39 EDT
*** Bug 492087 has been marked as a duplicate of this bug. ***
Comment 27 Markus Keller CLA 2017-03-16 13:31:01 EDT
This bug should have been resolved for 4.7M2. Marking as fixed.