Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java 9 (JDK-9) support for guice #1085

Closed
felixblaschke opened this issue Mar 14, 2017 · 51 comments
Closed

Java 9 (JDK-9) support for guice #1085

felixblaschke opened this issue Mar 14, 2017 · 51 comments
Assignees

Comments

@felixblaschke
Copy link

felixblaschke commented Mar 14, 2017

I am evaluating my projects with a pre-release Java 9 SDK. It's using recent guice that fails to inject the dependencies. Guice is trying to alter some classes in java.base module via setAccessible(...) Reflection call. Many other DI frameworks suffer from the same issue.

Are you currently working on Java 9 support for guice?

I used Java(TM) SE Runtime Environment (build 9-ea+159) and guice 1.4.1. Build target is Java 1.8.

Here is the stack trace that occured when DI-ing:

Exception in thread "Thread-0" java.lang.ExceptionInInitializerError
      at com.google.inject.internal.cglib.reflect.$FastClass$Generator.getProtectionDomain(FastClass.java:73)
      at com.google.inject.internal.cglib.core.$AbstractClassGenerator.create(AbstractClassGenerator.java:206)
      at com.google.inject.internal.cglib.reflect.$FastClass$Generator.create(FastClass.java:65)
      at com.google.inject.internal.BytecodeGen.newFastClassForMember(BytecodeGen.java:252)
      at com.google.inject.internal.BytecodeGen.newFastClassForMember(BytecodeGen.java:203)
      at com.google.inject.internal.ProviderMethod.create(ProviderMethod.java:69)
      at com.google.inject.internal.ProviderMethodsModule.createProviderMethod(ProviderMethodsModule.java:275)
      at com.google.inject.internal.ProviderMethodsModule.getProviderMethods(ProviderMethodsModule.java:144)
      at com.google.inject.internal.ProviderMethodsModule.configure(ProviderMethodsModule.java:123)
      at com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:340)
      at com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:349)
      at com.google.inject.spi.Elements.getElements(Elements.java:110)
      at com.google.inject.internal.InjectorShell$Builder.build(InjectorShell.java:138)
      at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:104)
      at com.google.inject.Guice.createInjector(Guice.java:99)
      at de.client.main.Factory.createInjector(Factory.java:248)
      at de.client.main.Main$1$1.run(Main.java:76)
      at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @a42cff
      at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:335)
      at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:278)
      at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:196)
      at java.base/java.lang.reflect.Method.setAccessible(Method.java:190)
      at com.google.inject.internal.cglib.core.$ReflectUtils$1.run(ReflectUtils.java:52)
      at java.base/java.security.AccessController.doPrivileged(Native Method)
      at com.google.inject.internal.cglib.core.$ReflectUtils.<clinit>(ReflectUtils.java:42)
      ... 21 more

I can surpass that issue using the VM args --add-opens java.base/java.lang=ALL-UNNAMED

@brettwooldridge
Copy link

@felixblaschke This is particularly the fault of cglib. Google "Java 9 cglib" to find relevant discussions.

@dimo414
Copy link
Contributor

dimo414 commented Apr 16, 2017

@brettwooldridge are you referring to this issue? Linking to the page(s) you think are relevant is much more helpful than suggesting a Google search.

@brettwooldridge
Copy link

I actually wasn't referring to any one specific page. But as long as you're linking to one, I'll throw this abridged version of War and Peace into the mix.

@tschulte
Copy link

cglib 3.2.5 seems to fix this issue. But Guice seems to repackage cglib. Therefore it seems I am not able to just include cglib 3.2.5?

But I built my own version of guice using cglib 3.2.5 and now I can launch my application with Java 9-ea+162. You should consider creating a new version of Guice with cglib 3.2.5.

@deanhiller
Copy link

yes. please release new version of guice

@tibbe
Copy link

tibbe commented Jun 6, 2017

I'm also suffering from this problem. Releasing a new version or unbundling cglib would be nice.

@ijuma
Copy link

ijuma commented Aug 9, 2017

The first RC for Java 9 has been published:

http://mail.openjdk.java.net/pipermail/jdk9-dev/2017-August/005940.html

So, it seems like a good time to fix this (bumping the cglib version seems like a simple fix too).

@AlanBateman
Copy link

The java.lang package is open for so-call deep reflection by default so this allows existing hacks to continue to work for a bit longer. In the future then this will cause so Guice and/or cglib should look at the new Lookup.defineClass, it's the support way for libraries to inject classes.

@bartlomiej-dawidow
Copy link

Java 9 was released a few weeks ago, it's high time to update Guice.

@DigitalSmile
Copy link

What is the status of this issue? Is someone from contributors aware of this?

@stIncMale
Copy link

@DigitalSmile The whole project seems to be abandoned. Despite almost everyone uses Spring, previously I at least knew that there is a pure DI framework. And now I know of no alternatives to Spring :(

@rototor
Copy link

rototor commented Dec 5, 2017

FYI: I have a branch in which I made everything work with JDK 9 - by unbundling and upgrading the dependencies. I'm using this in production on JDK9 for over a month now without a problem. The branch has the deployment settings changed to work with my local Artefactory, so if you want to use this you have to adjust the settings.

@dimo414
Copy link
Contributor

dimo414 commented Dec 7, 2017

Guice is definitely not abandoned! But it's currently maintained by volunteers, and pulling everything together for a new Open Source release just hasn't been prioritized. This will get fixed, but I can't offer any sort of ETA at the moment :(

@DigitalSmile
Copy link

@dimo414 thanks for the insight and heads up. I can understand, it is an Open Source code and is supported by community, still it is stated very clearly, that Google has a "patronage" over this project... For months and months there are no activities (or at least all other community cannot see this).
Can we have just plans or milestones and/or some news uncovered? Because I can agree with @stIncMale - it's just look like abandoned project...

Thanks for all your effort guys! The lib is awesome.

@dimo414
Copy link
Contributor

dimo414 commented Dec 12, 2017

FYI we're trying to get the OS build moving again. Stay posted!

@DigitalSmile
Copy link

@dimo414 are you going to fully support Jigsaw or it's just a fix for running with JDK9?

@dimo414
Copy link
Contributor

dimo414 commented Dec 14, 2017

@DigitalSmile I'm not in a position to commit to supporting anything :) but we certainly want Guice to work wherever possible, and once the OS build is fixed it will be easier to address these issues.

@mkurz
Copy link
Contributor

mkurz commented Dec 14, 2017

We get a different exception when running Guice 4.1.0 with Java 9: error.log

This IllegalArgumentException is caused by the outdated ASM version Guice is using. Currently that is 5.0.3 here.

The line in the ASM source that causes the problem is that one here which explicitly makes Java versions greater than 8 fail. In ASM version 6.0 that line is definitely compatible with Java 9.

ASM 6.0 brings full support for Java 9 class files. Read the release announcement here:

The ASM 6.0 version has been released, providing full support for Java 9 class files.

@dimo414 Please update to ASM 6.0 (by replacing the jar).

@rototor You may want to upgrade to ASM 6.0 in your branch you mentioned above.

@slnowak
Copy link

slnowak commented Jan 14, 2018

@dimo414 there are at least 3 forks I've seen that fixes it to the point where guice compiles and runs on jdk9.
That would be a good start since this is a matter of few lines of code.

Although there are tools like https://jitpack.io/ that allows you to basically build these forks and use them as maven dependency, I believe there are companies that are not exactly fine with that.
So simply fixing it to the point where it compiles and works and publishing it to maven repo with minor version increased could convince people that at least project is alive (unless they clone the git repo and check there's almost no activity on master during last few months).
Can we have some ETA?

@anthraxx
Copy link

@sameb @lukesandberg can you please take a look at the referenced PRs 🐱 ? It is in fact a blocker now and soon a whole year passed since opening this issue.
Otherwise i guess i need to fork and build own versions with the patches applied so it becomes useful again. 😞

@tbalzer
Copy link

tbalzer commented Jan 15, 2018

I have to agree this is a royal nuisance in the buttocks. Guice + JDK9 is not really usable for us due to this issue and JDK9 has been in GA for almost 4 months now. It almost looks as if this project is orphaned.

@kashike
Copy link
Contributor

kashike commented Jan 21, 2018

I'd have to agree - it looks as if the public version of Guice has been left to rot. 😿

@netdpb
Copy link
Member

netdpb commented Jan 23, 2018

We're working right now to get our changes since e7bef34 merged in. Some of those changes get us closer to Java 9 support, and fix some of the issues in the PRs. After that, let's see what we have left to do.

@tbalzer
Copy link

tbalzer commented Feb 20, 2018

I have to agree with @anthraxx.

@ronshapiro / @netdpb : What is missing? Is there anything we could help you with? Additional testing?

@kamenik
Copy link

kamenik commented Feb 22, 2018

With this update, will guice be compatible with jdk10 too? It is waiting behind the corner.

@mkurz
Copy link
Contributor

mkurz commented Feb 22, 2018

To support Java 10 guice has to upgrade to ASM 6.1 when it is released. Right now it is in beta2: https://gitlab.ow2.org/asm/asm/tags

@netdpb
Copy link
Member

netdpb commented Feb 27, 2018

We're working on the 4.2 release, hopefully for this week.

@sameb
Copy link
Member

sameb commented Feb 28, 2018

guice 4.2 is released w/ java9 support.

@sameb sameb closed this as completed Feb 28, 2018
@anthraxx
Copy link

Thanks a lot for the work involved and taking care of this.
Guice is really a pretty amazing DI framework and I'm happy to see this finaly happened. Please keep giving it a tiny portion of love, it really deserves it 🎉

@bartlomiej-dawidow
Copy link

Thanks a lot for the new release. Missing bindings are now beautifully reported in the logs.

For the record though, we are still getting illegal access warnings:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.google.inject.internal.cglib.core.$ReflectUtils$1 (file:/Users/bartek/.m2/repository/com/google/inject/guice/4.2.0/guice-4.2.0.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of com.google.inject.internal.cglib.core.$ReflectUtils$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

@AlanBateman
Copy link

It use to useful to test Guice with --illegal-access=deny to catch any issues that might arise when access illegal access to classes or members of classes in the JDK modules is denied. For injection then maybe Guice could loook at using Lookup.defineClass itself rather than relying on its copy of cglib to hack into protected members of java.lang.ClassLoader.

@fcole90
Copy link

fcole90 commented Mar 9, 2018

Referenced this issue in guice package for Ubuntu 18.04: https://bugs.launchpad.net/guice/+bug/1754602

@mkurz
Copy link
Contributor

mkurz commented Mar 12, 2018

ASM 6.1 with Java 10 support has been released:
https://mail.ow2.org/wws/arc/asm/2018-03/msg00000.html
https://gitlab.ow2.org/asm/asm/tags

@mkurz
Copy link
Contributor

mkurz commented Mar 26, 2018

ASM 6.1.1 has been released, needed for Java 10 support.
@sameb what's the plan here? Will you upgrade asm and release release 4.2.1?

@mkurz
Copy link
Contributor

mkurz commented May 30, 2018

ASM 6.2 released with better JDK 10 support and even with JDK 11 support already!
http://asm.ow2.io/versions.html
https://gitlab.ow2.org/asm/asm/tags
https://gitlab.ow2.org/asm/asm/issues/317830

@mkurz
Copy link
Contributor

mkurz commented Sep 1, 2018

asm 6.2.1 released.

@GedMarc
Copy link

GedMarc commented Sep 29, 2018

This looks like it has made a come back in JRE 11?

Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to module com.google.guice
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:340)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:280)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:198)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:192)
at com.google.guice@4.2.1/com.google.inject.internal.cglib.core.$ReflectUtils$1.run(ReflectUtils.java:61)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at com.google.guice@4.2.1/com.google.inject.internal.cglib.core.$ReflectUtils.(ReflectUtils.java:52)
at com.google.guice@4.2.1/com.google.inject.internal.cglib.reflect.$FastClassEmitter.(FastClassEmitter.java:67)
at com.google.guice@4.2.1/com.google.inject.internal.cglib.reflect.$FastClass$Generator.generateClass(FastClass.java:77)
at com.google.guice@4.2.1/com.google.inject.internal.cglib.core.$DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at com.google.guice@4.2.1/com.google.inject.internal.cglib.core.$AbstractClassGenerator.generate(AbstractClassGenerator.java:329)
at com.google.guice@4.2.1/com.google.inject.internal.cglib.core.$AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:93)
at com.google.guice@4.2.1/com.google.inject.internal.cglib.core.$AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:91)
at com.google.guice@4.2.1/com.google.inject.internal.cglib.core.internal.$LoadingCache$2.call(LoadingCache.java:54)
at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
at com.google.guice@4.2.1/com.google.inject.internal.cglib.core.internal.$LoadingCache.createEntry(LoadingCache.java:61)
at com.google.guice@4.2.1/com.google.inject.internal.cglib.core.internal.$LoadingCache.get(LoadingCache.java:34)
at com.google.guice@4.2.1/com.google.inject.internal.cglib.core.$AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:116)
at com.google.guice@4.2.1/com.google.inject.internal.cglib.core.$AbstractClassGenerator.create(AbstractClassGenerator.java:291)
at com.google.guice@4.2.1/com.google.inject.internal.cglib.reflect.$FastClass$Generator.create(FastClass.java:65)
at com.google.guice@4.2.1/com.google.inject.internal.BytecodeGen.newFastClassForMember(BytecodeGen.java:258)
at com.google.guice@4.2.1/com.google.inject.internal.BytecodeGen.newFastClassForMember(BytecodeGen.java:207)
at com.google.guice@4.2.1/com.google.inject.internal.ProviderMethod.create(ProviderMethod.java:69)
at com.google.guice@4.2.1/com.google.inject.internal.ProviderMethodsModule.createProviderMethod(ProviderMethodsModule.java:272)
at com.google.guice@4.2.1/com.google.inject.internal.ProviderMethodsModule.getProviderMethods(ProviderMethodsModule.java:116)
at com.google.guice@4.2.1/com.google.inject.internal.ProviderMethodsModule.configure(ProviderMethodsModule.java:100)
at com.google.guice@4.2.1/com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:344)
at com.google.guice@4.2.1/com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:353)
at com.google.guice@4.2.1/com.google.inject.PrivateModule.install(PrivateModule.java:171)
at com.jwebmp.guicedpersistence/com.jwebmp.guicedpersistence.injectors.JpaPersistPrivateModule.configure(JpaPersistPrivateModule.java:50)
at com.google.guice@4.2.1/com.google.inject.PrivateModule.configure(PrivateModule.java:101)
at com.google.guice@4.2.1/com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:344)
at com.google.guice@4.2.1/com.google.inject.AbstractModule.install(AbstractModule.java:103)
at com.jwebmp.guicedpersistence/com.jwebmp.guicedpersistence.db.AbstractDatabaseProviderModule.configure(AbstractDatabaseProviderModule.java:109)
at com.google.guice@4.2.1/com.google.inject.AbstractModule.configure(AbstractModule.java:61)
at com.google.guice@4.2.1/com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:344)
at com.google.guice@4.2.1/com.google.inject.spi.Elements.getElements(Elements.java:103)
at com.google.guice@4.2.1/com.google.inject.internal.InjectorShell$Builder.build(InjectorShell.java:137)
at com.google.guice@4.2.1/com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:103)
... 6 more

  • [SEVERE]

@cheister
Copy link

@GedMarc see #1205

@AlanBateman
Copy link

The InaccessibleObjectException in GerMarc's comment is because Guice is in a named module and it trying to hack the protected ClassLoader.defineClass method to call it from the wrong context. It can be worked around, on a temporary basis, with --add-opens java.base/java.lang=com.google.guice of course but the right solution is to get Guice fixed to use Lookup.defineClass. The reason the behavior is different when Guice is deployed on the class path is because the JDK (in JDK 9, 10 and 11) opens all the packages that existed in JDK 8 to code on the class path (not all modules) for so-called illegal access. This keeps most existing hacks working for a few releases to give the maintainers of libraries time to replace them.

@GedMarc
Copy link

GedMarc commented Sep 30, 2018

Naw this was from a push up from JRE10, so it was working fine in JPMS,

I think ALL-MODULES got removed because as you pointed out exposing directly to the google guice package does get around it but using ALL-MODULES and this still comes up... Doing the module path exclusion tho makes a lot more errors later on
I've also noticed all AOP Guice in JRE11 is completely non-functional where in JRE 10 it was perfect ;)

I think there is a significant change between 10 and 11 that is breaking the injection library with regards to the exposures...

@AlanBateman
Copy link

There are no changes in this area in JDK 11, the set of packages that are opened for illegal access to code on the class path is the same as JDK 9 and JDK 10. This doesn't help Guice in the example because it is deployed as a named module, not the class path (unnamed module). The right thing is course to fix Guice to use Lookup.defineClass.

@GedMarc
Copy link

GedMarc commented Sep 30, 2018

Hmmm, It doesn't make sense then.
Running the exact same app in JRE 10 with named modules is 100% without any command line parameters or exclusions, simply switching from 10 to JRE 11 causes the issue. Adding the above mentioned ALL-MODULES does not work at all, in fact no difference is made in execution at all.

Setting it to --add-opens java.base/java.lang=com.google.guice,javassist does work with it specified explicitely, (Hence ALL-MODULES removed theory). But what you're saying doesn't make sense with what is happening?

Adding in the program parameter -Dcom.google.inject.internal.cglib.$experimental_asm7=true does assist somewhat but no AOP is available.

@AlanBateman
Copy link

InaccessibleObjectException is because Guice is in a named module, you'll see exactly the same exception with JDK 9, 10 and 11. If Guice is on the class path then the hack will work although you should see an "Illegal reflective access" warning to point out that it will break once the java.base module is fully encapsulated.

@GedMarc
Copy link

GedMarc commented Sep 30, 2018

Thanks Alan, indeed it was cglib in guice causing,

I can run with the opens exposed, and the parameter configred.

ShoOgino pushed a commit to ShoOgino/guiceFile that referenced this issue Oct 14, 2020
ShoOgino pushed a commit to ShoOgino/guiceMethod that referenced this issue Oct 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests