Guice: Suporte a Java 9 (JDK-9) para guice

Criado em 14 mar. 2017  ·  51Comentários  ·  Fonte: google/guice

Estou avaliando meus projetos com um Java 9 SDK de pré-lançamento. Está usando guice recente que não consegue injetar as dependências. Guice está tentando alterar algumas classes no módulo java.base via chamada de setAccessible(...) Reflection. Muitos outros frameworks de DI sofrem do mesmo problema.

Você está trabalhando atualmente no suporte a Java 9 para guice?

Usei Java(TM) SE Runtime Environment (build 9-ea+159) e guice 1.4.1 . O alvo da compilação é Java 1.8 .

Aqui está o rastreamento de pilha que ocorreu ao fazer o DI:

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 <strong i="15">@a42cff</strong>
      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

Posso superar esse problema usando os argumentos da VM --add-opens java.base/java.lang=ALL-UNNAMED

Comentários muito úteis

O Java 9 foi lançado há algumas semanas, é hora de atualizar o Guice.

Todos 51 comentários

@felixblaschke Isso é particularmente culpa do cglib. Google "Java 9 cglib" para encontrar discussões relevantes.

@brettwooldridge, você está se referindo a esse problema ? Criar um link para as páginas que você considera relevantes é muito mais útil do que sugerir uma pesquisa no Google.

Na verdade, não estava me referindo a nenhuma página específica. Mas, desde que você esteja se conectando a um, vou colocar esta versão resumida de Guerra e paz na mistura.

O cglib 3.2.5 parece corrigir esse problema. Mas Guice parece reempacotar o cglib. Portanto, parece que não consigo apenas incluir cglib 3.2.5?

Mas eu construí minha própria versão do guice usando cglib 3.2.5 e agora posso iniciar meu aplicativo com Java 9-ea + 162. Você deve considerar a criação de uma nova versão do Guice com cglib 3.2.5.

sim. por favor, libere uma nova versão do guice

Eu também estou sofrendo desse problema. Lançar uma nova versão ou descompactar o cglib seria bom.

O primeiro RC para Java 9 foi publicado:

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

Portanto, parece um bom momento para consertar isso (ultrapassar a versão cglib também parece uma solução simples).

O pacote java.lang está aberto para a chamada reflexão profunda por padrão, então isso permite que os hacks existentes continuem a funcionar por um pouco mais de tempo. No futuro, isso fará com que Guice e / ou cglib examinem o novo Lookup.defineClass, é a forma de suporte para bibliotecas injetar classes.

O Java 9 foi lançado há algumas semanas, é hora de atualizar o Guice.

Qual é o status deste problema? Alguém dos colaboradores está ciente disso?

@DigitalSmile Todo o projeto parece ter sido abandonado. Apesar de quase todo mundo usar o Spring, antes eu pelo menos sabia que existe um framework DI puro. E agora não conheço alternativas para o Spring :(

Para sua informação: Eu tenho uma filial na qual fiz tudo funcionar com o JDK 9 - desagregando e atualizando as dependências. Estou usando isso em produção no JDK9 há mais de um mês sem problemas. O branch tem as configurações de implantação alteradas para funcionar com meu Artefactory local, então se você quiser usar isso, você terá que ajustar as configurações.

Guice definitivamente não está abandonado! Mas atualmente é mantido por voluntários, e reunir tudo para um novo lançamento de código aberto simplesmente não foi priorizado. Isso será corrigido, mas não posso oferecer nenhum tipo de HEC no momento :(

@ dimo414 obrigado pelo insight e atenção. Eu posso entender, é um código Open Source e é apoiado pela comunidade, ainda é afirmado de forma muito clara, que o Google tem um "patrocínio" sobre este projeto ... Por meses e meses não há atividades (ou pelo menos todas as outras comunidade não pode ver isso).
Podemos ter apenas planos ou marcos e / ou algumas notícias descobertas? Porque posso concordar com @stIncMale - parece um projeto abandonado ...

Obrigado por todo o seu esforço pessoal! A lib é incrível.

Para sua informação, estamos tentando fazer com que a construção do sistema operacional volte a funcionar. Fique informado!

@ dimo414, você oferecerá suporte total ao Jigsaw ou será apenas uma correção para executar o JDK9?

@DigitalSmile Não estou em posição de me comprometer a apoiar nada :) mas certamente queremos que o Guice trabalhe sempre que possível, e uma vez que a compilação do sistema operacional seja corrigida, será mais fácil resolver esses problemas.

Obtemos uma exceção diferente ao executar o Guice 4.1.0 com Java 9: error.log

Este IllegalArgumentException é causado pela versão ASM desatualizada que o Guice está usando. Atualmente, isso está 5.0.3 aqui .

A linha na origem ASM que causa o problema é aquela aqui que explicitamente faz com que as versões Java maiores que 8 falhem. No ASM versão 6.0, essa linha é definitivamente compatível com Java 9.

O ASM 6.0 oferece suporte completo para arquivos de classe Java 9. Leia o anúncio de lançamento aqui :

A versão ASM 6.0 foi lançada, fornecendo suporte completo para arquivos de classe Java 9.

@ dimo414 Atualize para ASM 6.0 (substituindo o jar).

@rototor Você pode querer atualizar para ASM 6.0 em seu branch que você mencionou acima.

@ dimo414 existem pelo menos 3 garfos que eu vi que corrigem até o ponto em que guice compila e roda em jdk9.
Isso seria um bom começo, pois se trata de uma questão de poucas linhas de código.

Embora existam ferramentas como https://jitpack.io/ que permitem basicamente construir esses garfos e usá-los como dependência do maven, acredito que existem empresas que não estão exatamente bem com isso.
Então, simplesmente corrigi-lo até o ponto em que ele compila e funciona e publicá-lo no repo do maven com a versão secundária aumentada poderia convencer as pessoas de que pelo menos o projeto está vivo (a menos que clonem o repo git e verifiquem que quase não há atividade no master durante os últimos meses )
Podemos ter algum HEC?

@sameb @lukesandberg, por favor, dê uma olhada nos PRs mencionados: cat:? Na verdade, é um bloqueador agora e logo se passou um ano inteiro desde a abertura desta edição.
Caso contrário, acho que preciso bifurcar e construir versões próprias com os patches aplicados para que se torne útil novamente. : desapontado:

Tenho que concordar que isso é um incômodo real nas nádegas. O Guice + JDK9 não pode ser usado por nós devido a esse problema e o JDK9 está no GA há quase 4 meses. Quase parece que este projeto está órfão.

Eu tenho que concordar - parece que a versão pública do Guice foi deixada para apodrecer. : cry_cat_face:

Estamos trabalhando agora para obter nossas alterações desde a fusão de e7bef34ef6379735e2a58df1b23f351bb7e30e44. Algumas dessas alterações nos aproximam do suporte Java 9 e corrigem alguns dos problemas nos PRs. Depois disso, vamos ver o que nos resta fazer.

aopalliance:aopalliance e javax.inject:javax.inject parecem estar mortos. : ligeiramente_frowning_face:

d95c8c0cdd029a8cfda781bf48976255e059d45a atualizou cglib para java 9 e o seguinte commit também abordou problemas de Java 9. Você quer experimentar?

Vejo que algo está acontecendo, mestre. Podemos esperar o lançamento em breve?

@ronshapiro Sou capaz de rodar com Java 9 dentro do meu IDE, mas não em tempo de execução - guice ainda não tem uma classe Automatic-Module-Name ou module-info.java .

@ronshapiro O instantâneo atual funciona bem para o que testamos. Obtendo mensagens de exceção adequadas e finalmente úteis, rastros e coisas do tipo ... acho que é uma boa maneira: smile_cat:

@kashike obrigado pelo lembrete daqueles - adicionado em # 1155.

O que exatamente sobrou? Eu simplesmente acho que é sólido o suficiente para um lançamento, quaisquer pequenas alterações adicionais relacionadas ao java9 podem entrar em um ponto de correção. Guice com java9 é realmente inutilizável e está piorando e desgastando com o passar do tempo.
O que quer que tenha sobrado, parece bom o suficiente para obter uma versão agora e uma possível correção mais tarde.

Tenho que concordar com @anthraxx.

@ronshapiro / @netdpb : O que está faltando? Podemos ajudá-lo em alguma coisa? Testes adicionais?

Com esta atualização, o guice será compatível com o jdk10 também? Ele está esperando atrás da esquina.

Para oferecer suporte ao Java 10, o guice deve atualizar para ASM 6.1 quando for lançado. No momento, está em beta2: https://gitlab.ow2.org/asm/asm/tags

Estamos trabalhando na versão 4.2, esperançosamente para esta semana.

guice 4.2 é lançado com suporte a java9.

Muito obrigado pelo trabalho envolvido e por cuidar disso.
Guice é realmente um framework de DI incrível e estou feliz em ver que isso finalmente aconteceu. Por favor, continue dando a ele uma pequena porção de amor, ele realmente merece: tada:

Muito obrigado pelo novo lançamento. Ligações ausentes agora são lindamente relatadas nos logs.

Para registro, ainda estamos recebendo avisos de acesso ilegal:

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

É útil testar o Guice com --illegal-access=deny para detectar quaisquer problemas que possam surgir quando o acesso ilegal a classes ou membros de classes nos módulos JDK é negado. Para injeção, talvez Guice pudesse olhar para o próprio Lookup.defineClass em vez de depender de sua cópia do cglib para invadir membros protegidos de java.lang.ClassLoader.

Referenciou esse problema no pacote guice para Ubuntu 18.04: https://bugs.launchpad.net/guice/+bug/1754602

ASM 6.1.1 foi lançado, necessário para suporte Java 10.
@sameb qual é o plano aqui? Você atualizará o ASM e lançará a versão 4.2.1?

asm 6.2.1 lançado.

Isso parece que voltou no JRE 11?

Causado por: java.lang.reflect.InaccessibleObjectException: não é possível fazer java.lang.Class java.lang.ClassLoader.defineClass (java.lang.String, byte [], int, int, java.security.ProtectionDomain) java.lang.ClassFormatError acessível: o módulo java.base não "abre java.lang" para o módulo com.google.guice
em java.base / java.lang.reflect.AccessibleObject.checkCanSetAccessible (AccessibleObject.java:340)
em java.base / java.lang.reflect.AccessibleObject.checkCanSetAccessible (AccessibleObject.java:280)
em java.base / java.lang.reflect.Method.checkCanSetAccessible (Method.java:198)
em java.base / java.lang.reflect.Method.setAccessible (Method.java:192)
em com.google. [email protected]/com.google.inject.internal.cglib.core. $ ReflectUtils $ 1.run (ReflectUtils.java:61)
em java.base / java.security.AccessController.doPrivileged (método nativo)
em com.google. [email protected]/com.google.inject.internal.cglib.core. $ ReflectUtils.(ReflectUtils.java:52)
em com.google. [email protected]/com.google.inject.internal.cglib.reflect. $ FastClassEmitter.(FastClassEmitter.java:67)
em com.google. [email protected]/com.google.inject.internal.cglib.reflect. $ FastClass $ Generator.generateClass (FastClass.java:77)
em com.google. [email protected]/com.google.inject.internal.cglib.core. $ DefaultGeneratorStrategy.generate (DefaultGeneratorStrategy.java:25)
em com.google. [email protected]/com.google.inject.internal.cglib.core. $ AbstractClassGenerator.generate (AbstractClassGenerator.java:329)
em com.google. [email protected]/com.google.inject.internal.cglib.core. $ AbstractClassGenerator $ ClassLoaderData $ 3.apply (AbstractClassGenerator.java:93)
em com.google. [email protected]/com.google.inject.internal.cglib.core. $ AbstractClassGenerator $ ClassLoaderData $ 3.apply (AbstractClassGenerator.java:91)
em com.google. [email protected]/com.google.inject.internal.cglib.core.internal. $ LoadingCache $ 2.call (LoadingCache.java:54)
em java.base / java.util.concurrent.FutureTask.run $$$ capture (FutureTask.java:264)
em java.base / java.util.concurrent.FutureTask.run (FutureTask.java)
em com.google. [email protected]/com.google.inject.internal.cglib.core.internal. $ LoadingCache.createEntry (LoadingCache.java:61)
em com.google. [email protected]/com.google.inject.internal.cglib.core.internal. $ LoadingCache.get (LoadingCache.java:34)
em com.google. [email protected]/com.google.inject.internal.cglib.core. $ AbstractClassGenerator $ ClassLoaderData.get (AbstractClassGenerator.java:116)
em com.google. [email protected]/com.google.inject.internal.cglib.core. $ AbstractClassGenerator.create (AbstractClassGenerator.java:291)
em com.google. [email protected]/com.google.inject.internal.cglib.reflect. $ FastClass $ Generator.create (FastClass.java:65)
em com.google. [email protected]/com.google.inject.internal.BytecodeGen.newFastClassForMember (BytecodeGen.java:258)
em com.google. [email protected]/com.google.inject.internal.BytecodeGen.newFastClassForMember (BytecodeGen.java:207)
em com.google. [email protected]/com.google.inject.internal.ProviderMethod.create (ProviderMethod.java:69)
em com.google. [email protected]/com.google.inject.internal.ProviderMethodsModule.createProviderMethod (ProviderMethodsModule.java:272)
em com.google. [email protected]/com.google.inject.internal.ProviderMethodsModule.getProviderMethods (ProviderMethodsModule.java:116)
em com.google. [email protected]/com.google.inject.internal.ProviderMethodsModule.configure (ProviderMethodsModule.java:100)
em com.google. [email protected]/com.google.inject.spi.Elements $ RecordingBinder.install (Elements.java:344)
em com.google. [email protected]/com.google.inject.spi.Elements $ RecordingBinder.install (Elements.java:353)
em com.google. [email protected]/com.google.inject.PrivateModule.install (PrivateModule.java:171)
em com.jwebmp.guicedpersistence / com.jwebmp.guicedpersistence.injectors.JpaPersistPrivateModule.configure (JpaPersistPrivateModule.java:50)
em com.google. [email protected]/com.google.inject.PrivateModule.configure (PrivateModule.java:101)
em com.google. [email protected]/com.google.inject.spi.Elements $ RecordingBinder.install (Elements.java:344)
em com.google. [email protected]/com.google.inject.AbstractModule.install (AbstractModule.java:103)
em com.jwebmp.guicedpersistence / com.jwebmp.guicedpersistence.db.AbstractDatabaseProviderModule.configure (AbstractDatabaseProviderModule.java:109)
em com.google. [email protected]/com.google.inject.AbstractModule.configure (AbstractModule.java:61)
em com.google. [email protected]/com.google.inject.spi.Elements $ RecordingBinder.install (Elements.java:344)
em com.google. [email protected]/com.google.inject.spi.Elements.getElements (Elements.java:103)
em com.google. [email protected]/com.google.inject.internal.InjectorShell $ Builder.build (InjectorShell.java:137)
em com.google. [email protected]/com.google.inject.internal.InternalInjectorCreator.build (InternalInjectorCreator.java:103)
... mais 6

  • [FORTE]

A InaccessibleObjectException no comentário de GerMarc é porque Guice está em um módulo nomeado e está tentando hackear o método ClassLoader.defineClass protegido para chamá-lo do contexto errado. Isso pode ser contornado, em uma base temporária, com --add-opens java.base/java.lang=com.google.guice claro, mas a solução certa é consertar o Guice para usar Lookup.defineClass. A razão pela qual o comportamento é diferente quando o Guice é implantado no caminho da classe é porque o JDK (no JDK 9, 10 e 11) abre todos os pacotes que existiam no JDK 8 para codificar no caminho da classe (não todos os módulos) para assim- chamado de acesso ilegal. Isso mantém a maioria dos hacks existentes trabalhando por alguns lançamentos para dar aos mantenedores das bibliotecas tempo para substituí-los.

Não, isso veio de um push up do JRE10, então estava funcionando bem no JPMS,

Acho que TODOS OS MÓDULOS foram removidos porque, como você apontou, expor diretamente ao pacote guice do google contorna isso, mas usando TODOS OS MÓDULOS e isso ainda surge ... Fazer a exclusão do caminho do módulo, embora cometa muitos mais erros mais tarde
Também notei que todo o AOP Guice no JRE11 é completamente não funcional, enquanto no JRE 10 era perfeito;)

Acho que há uma mudança significativa entre 10 e 11 que está quebrando a biblioteca de injeção no que diz respeito às exposições ...

Não há mudanças nesta área no JDK 11, o conjunto de pacotes que são abertos para acesso ilegal ao código no caminho da classe é o mesmo que JDK 9 e JDK 10. Isso não ajuda Guice no exemplo porque está implantado como um módulo nomeado, não o caminho da classe (módulo sem nome). O certo é consertar o Guice para usar Lookup.defineClass.

Hmmm, então não faz sentido.
Executar exatamente o mesmo aplicativo no JRE 10 com módulos nomeados é 100% sem nenhum parâmetro de linha de comando ou exclusões, simplesmente alternar de 10 para JRE 11 causa o problema. Adicionar os TODOS-MÓDULOS mencionados acima não funciona, na verdade nenhuma diferença é feita na execução.

Configurando-o como --add-opens java.base / java.lang = com.google.guice, javassist funciona com ele especificado explicitamente, (Conseqüentemente, ALL-MODULES remove a teoria). Mas o que você está dizendo não faz sentido com o que está acontecendo?

Adicionar o parâmetro do programa -Dcom.google.inject.internal.cglib. $ Experimental_asm7 = true ajuda um pouco, mas nenhum AOP está disponível.

InaccessibleObjectException é porque Guice está em um módulo nomeado, você verá exatamente a mesma exceção com JDK 9, 10 e 11. Se Guice estiver no caminho de classe, o hack funcionará, embora você deva ver um aviso de "Acesso reflexivo ilegal" para saliente que ele será interrompido assim que o módulo java.base estiver totalmente encapsulado.

Obrigado Alan, na verdade foi cglib in guice causando,

Posso executar com as aberturas expostas e o parâmetro configurado.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

afghl picture afghl  ·  5Comentários

vgarmash picture vgarmash  ·  4Comentários

Cybermaxke picture Cybermaxke  ·  7Comentários

laurentmartelli picture laurentmartelli  ·  11Comentários

dxiao picture dxiao  ·  4Comentários