I am trying to see how Weld CDI container can work with JPMS. So I have the following configuration.
I have my named module and weld-se-shaded as automatic module. In my module I have
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 class
package com.foo;
import javax.enterprise.context.Dependent;
@Dependent
public class NewBean {
public void doIt() {
System.out.println("I am doing it");
}
}
And this is the result
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 weld.se.shaded@3.0.2-SNAPSHOT/org.jboss.weld.executor.AbstractExecutorServices.checkForExceptions(AbstractExecutorServices.java:72)
at weld.se.shaded@3.0.2-SNAPSHOT/org.jboss.weld.executor.AbstractExecutorServices.invokeAllAndCheckForExceptions(AbstractExecutorServices.java:58)
at weld.se.shaded@3.0.2-SNAPSHOT/org.jboss.weld.executor.AbstractExecutorServices.invokeAllAndCheckForExceptions(AbstractExecutorServices.java:66)
at weld.se.shaded@3.0.2-SNAPSHOT/org.jboss.weld.bootstrap.ConcurrentBeanDeployer.createClassBeans(ConcurrentBeanDeployer.java:65)
at weld.se.shaded@3.0.2-SNAPSHOT/org.jboss.weld.bootstrap.BeanDeployment.createBeans(BeanDeployment.java:256)
at weld.se.shaded@3.0.2-SNAPSHOT/org.jboss.weld.bootstrap.WeldStartup.deployBeans(WeldStartup.java:422)
at weld.se.shaded@3.0.2-SNAPSHOT/org.jboss.weld.bootstrap.WeldBootstrap.deployBeans(WeldBootstrap.java:83)
at weld.se.shaded@3.0.2-SNAPSHOT/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 weld.se.shaded@3.0.2-SNAPSHOT/org.jboss.weld.security.GetAccessibleCopyOfMember.of(GetAccessibleCopyOfMember.java:38)
at weld.se.shaded@3.0.2-SNAPSHOT/org.jboss.weld.security.GetAccessibleCopyOfMember.run(GetAccessibleCopyOfMember.java:44)
at weld.se.shaded@3.0.2-SNAPSHOT/org.jboss.weld.security.GetAccessibleCopyOfMember.run(GetAccessibleCopyOfMember.java:26)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at weld.se.shaded@3.0.2-SNAPSHOT/org.jboss.weld.injection.FieldInjectionPoint.<init>(FieldInjectionPoint.java:65)
How to explain this exception
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
There is a table here
from which I can understand that automatic module can read named (application) module. Then why it doesn't?
You should probably try replacing
exports com.foo
in your module-info.java
with
opens com.foo
The opens
directive in a module declaration declares a package to be open to allow all types in the package, and all their members, not just public types and their public members to be reflected on by APIs that support private access or a way to bypass or suppress default Java language access control checks.