2017-09-18 60 views
3

我想看看焊接CDI容器如何与JPMS一起工作。所以我有以下配置。自动模块可以在Java 9中读取导出包中已命名模块的类吗?

我有我的命名模块和焊接se-shaded作为自动模块。 在我的模块我有

module my.module { 
    requires weld.se.shaded; 
    exports com.foo; 
} 

的NewClass

package com.foo; 

import javax.enterprise.context.ApplicationScoped; 
import javax.inject.Inject; 

@ApplicationScoped 
public class NewClass { 

    @Inject 
    private NewBean bean; 

    public void doIt() { 
     bean.doIt(); 
    } 

} 

NewBean类

package com.foo; 

import javax.enterprise.context.Dependent; 

@Dependent 
public class NewBean { 

    public void doIt() { 
     System.out.println("I am doing it"); 
    } 
} 

这是结果

Sep 18, 2017 2:33:12 PM org.jboss.weld.bootstrap.WeldStartup <clinit> 
INFO: WELD-000900: 3.0.2 (2017-09-18 08:49) 
Sep 18, 2017 2:33:12 PM org.jboss.weld.environment.deployment.discovery.ReflectionDiscoveryStrategy processAnnotatedDiscovery 
INFO: WELD-ENV-000014: Falling back to Java Reflection for bean-discovery-mode="annotated" discovery. Add org.jboss:jandex to the classpath to speed-up startup. 
Sep 18, 2017 2:33:12 PM org.jboss.weld.bootstrap.WeldStartup startContainer 
INFO: WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously. 
Exception in thread "main" java.lang.reflect.InaccessibleObjectException 
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:488) 
    at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:590) 
    at java.base/java.util.concurrent.ForkJoinTask.get(ForkJoinTask.java:996) 
    at [email protected]/org.jboss.weld.executor.AbstractExecutorServices.checkForExceptions(AbstractExecutorServices.java:72) 
    at [email protected]/org.jboss.weld.executor.AbstractExecutorServices.invokeAllAndCheckForExceptions(AbstractExecutorServices.java:58) 
    at [email protected]/org.jboss.weld.executor.AbstractExecutorServices.invokeAllAndCheckForExceptions(AbstractExecutorServices.java:66) 
    at [email protected]/org.jboss.weld.bootstrap.ConcurrentBeanDeployer.createClassBeans(ConcurrentBeanDeployer.java:65) 
    at [email protected]/org.jboss.weld.bootstrap.BeanDeployment.createBeans(BeanDeployment.java:256) 
    at [email protected]/org.jboss.weld.bootstrap.WeldStartup.deployBeans(WeldStartup.java:422) 
    at [email protected]/org.jboss.weld.bootstrap.WeldBootstrap.deployBeans(WeldBootstrap.java:83) 
    at [email protected]/org.jboss.weld.environment.se.Weld.initialize(Weld.java:789) 
    at my.module/com.foo.NewMain.main(NewMain.java:47) 
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private com.foo.NewBean com.foo.NewClass.bean accessible: module my.module does not "opens com.foo" to module weld.se.shaded 
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:337) 
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:281) 
    at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:176) 
    at java.base/java.lang.reflect.Field.setAccessible(Field.java:170) 
    at [email protected]/org.jboss.weld.security.GetAccessibleCopyOfMember.of(GetAccessibleCopyOfMember.java:38) 
    at [email protected]/org.jboss.weld.security.GetAccessibleCopyOfMember.run(GetAccessibleCopyOfMember.java:44) 
    at [email protected]/org.jboss.weld.security.GetAccessibleCopyOfMember.run(GetAccessibleCopyOfMember.java:26) 
    at java.base/java.security.AccessController.doPrivileged(Native Method) 
    at [email protected]/org.jboss.weld.injection.FieldInjectionPoint.<init>(FieldInjectionPoint.java:65) 

如何解释这种异常

产生的原因:java.lang.reflect.InaccessibleObjectException:无法 制造商区域私人com.foo.NewBean com.foo.NewClass.bean访问: 模块my.module没有 “打开com.foo”到模块weld.se.shaded

有一个表hereenter image description here 从中我可以理解,自动模块可以读取命名(应用)模块。那为什么不呢?

回答

4

你应该尝试与

opens com.foo 

opens指令在模块声明替换

exports com.foo 

module-info.java声明一个包打开,让包中的所有类型,所有他们的成员,不仅仅是公共类型和他们的公共成员,可以通过支持私有访问的API或者绕过或压制默认的Java语言访问控制检查的API来体现。

+0

是的,它似乎解决了这个问题。你能解释一下'opens'和'exports'之间的区别吗? –

相关问题