Welcome to the public discussion channel for Weld - the CDI reference implementation (http://weld.cdi-spec.org/)
manovotn on master
Upgrade SpotBugs versions, Supp… (compare)
manovotn on master
WELD-2517: Weld SE - fix Securi… (compare)
at org.apache.deltaspike.cdise.weld.WeldContainerControl.boot(WeldContainerControl.java:71)
at de.hilling.junit.cdi.ContextControlWrapper.<init>(ContextControlWrapper.java:39)
at de.hilling.junit.cdi.ContextControlWrapper.<clinit>(ContextControlWrapper.java:22)
at de.hilling.junit.cdi.CdiTestJunitExtension.<init>(CdiTestJunitExtension.java:24)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.junit.platform.commons.util.ReflectionUtils.newInstance(ReflectionUtils.java:500)
at org.junit.platform.commons.util.ReflectionUtils.newInstance(ReflectionUtils.java:475)
at org.junit.jupiter.engine.extension.MutableExtensionRegistry.registerExtension(MutableExtensionRegistry.java:182)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at org.junit.jupiter.engine.extension.MutableExtensionRegistry.createRegistryFrom(MutableExtensionRegistry.java:123)
at org.junit.jupiter.engine.descriptor.ExtensionUtils.populateNewExtensionRegistryFromExtendWithAnnotation(ExtensionUtils.java:77)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.prepare(ClassBasedTestDescriptor.java:142)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.prepare(ClassBasedTestDescriptor.java:77)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$1(NodeTestTask.java:107)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:107)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:75)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs
<dependency>
<groupId>de.hilling.junit.cdi</groupId>
<artifactId>cdi-test-core</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se-core</artifactId>
<version>2.3.5.Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-spi</artifactId>
<version>2.3.SP2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.deltaspike.cdictrl</groupId>
<artifactId>deltaspike-cdictrl-weld</artifactId>
<version>1.9.1</version>
<scope>test</scope>
</dependency>
weld-se-core (and SPI) with weld-se-shaded
this object in such a case? After all, Weld invoked the observer method, so presumably this is already a proxy? Nevertheless, I'm noticing that if I invoke the business method using this interception does not occur. (I seem to recall this is possible in OpenWebBeans but can't remember for sure.)
this.myMethod(), it won't be considered a business method invocation (as you aren't going through a contextual reference) and as such it won't be intercepted.parameterParsers.select(new TypeLiteral<ParameterConverter<? super Message, ?>>() { }, new ParameterType.Literal("number")).get()Message I get dynamically as a parameter of the method using that.Map<Class<?>, TypeLiteral<?> for all possible types and then get it from there,Do you mean like this?
public <M> ... getParsedTypedParameters(M message, ...) {
...
parameterConverters.select(
(TypeLiteral<ParameterConverter<?, ?>>) (Object) new TypeLiteral<ParameterConverter<? super M, ?>>() { },
new ParameterType.Literal(type));
...
}I guess not, because that does not work due to
org.jboss.weld.exceptions.IllegalArgumentException: WELD-000623: Unknown type null.
at org.jboss.weld.resolution.CovariantTypes.isAssignableFrom(CovariantTypes.java:76) ~[weld-core-impl-3.1.2.Final.jar:3.1.2.Final]
The relevant code is not something I can push right now, it is still heavily wip and playing around to find the best way.
The cast to Object is necessary to fool the compiler as Weld is more intelligent / flexible than the compiler.
What I mean is,
parameterConverters is defined as @Inject @Any private volatile Instance<ParameterConverter<?, ?>> parameterConverters;
new TypeLiteral<ParameterConverter<? super Message, ?>>() { } compiler says error: incompatible types: inference variable U has incompatible equality constraints ParameterConverter<?,?>,ParameterConverter<? super Message,?>(TypeLiteral<ParameterConverter<?, ?>>) new TypeLiteral<ParameterConverter<? super Message, ?>>() { } compiler says error: incompatible types: <anonymous TypeLiteral<ParameterConverter<? super Message,?>>> cannot be converted to TypeLiteral<ParameterConverter<?,?>>(TypeLiteral<ParameterConverter<?, ?>>) (Object) new TypeLiteral<ParameterConverter<? super Message, ?>>() { } is works as expected for that class Message(TypeLiteral<ParameterConverter<?, ?>>) (Object) new TypeLiteral<ParameterConverter<? super M, ?>>() { } with signature as shown above, I get at runtime the Unknown type null. exception shown aboveClass -> TypeLiteral registry tactic.
Totally different question, are there happens-before guarantees regarding injection and post-construct methods in CDI?
What I mean is, if you traditionally instantiate a class and then set fields, for example using setters, you have to make sure to do it in a thread-safe way, either by thread-confinement, synchronisation or volatile.
I'm using CDI in a highly multi-threaded environment.
So if I inject beans by annotating the fields or setter methods and there-in set some fields or annotating some fields or methods and then use a post-construct method to set some fields.
Do I have to care for thread-safety, like marking the fields volatile or using AtomicReferences or synchronizing the access or are there some happens-before guarantees that make sure that injections and post-construction actions are completely done before exposing a bean instance to other threads?
LockedBean throughout Weld - https://github.com/weld/core/blob/master/impl/src/main/java/org/jboss/weld/contexts/beanstore/LockedBean.javaAnd additionally another question, I just managed to produce a stack overflow error.
A, B and C, several ApplicationScoped beans of A and B and one bean for CA beans gets Instance<B> injected into an @Inject methodB beans gets C injected into the constructor and calls a method on it directlyC bean gets Instance<A> injected into an @Inject methodThis results in a stackoverflow error due to the hen-and-egg problem that is not solved by the proxies in this case,
as the real instances are immediately needed in the @Inject methods.
If I do not call the method on C in the B constructor but call the method later in the program, no stack overflow error happens and everything is working fine.
Now my question is, how to properly solve this.
Do I need to use lazy initialization instead of the eager calculation of the derived data?
Or is there some better tactic available?
Using @PostConstruct in A and Cto derive the data is not sufficient and B is code coming from the user of my library, so it should work no matter how it is used in B.
Now my question is, how to properly solve this.
Honestly, if you want to solve it properly, then redesign the code to get rid of the circular dependency ;-)
Other than that, avoid calling the bean so early on.
If I recall correctly then:
one of the B beans gets C injected into the constructor and calls a method on it directly
is the problematic part that even proxies cannot workaround, at least I am not aware of to do that.