Skip to content

Commit

Permalink
Merge pull request #4137 from pdudits/spec-321
Browse files Browse the repository at this point in the history
 SPEC-321: Create instance at the and of AroundConstruct chain
  • Loading branch information
MattGill98 committed Aug 12, 2019
2 parents 6dd4489 + 036c793 commit 34ad29f
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 45 deletions.
2 changes: 1 addition & 1 deletion appserver/extras/embedded/shell/fixup.xml
Expand Up @@ -69,7 +69,7 @@
manifest file, so we need to explicitly touch it after updating
the manifest.
-->
<sleep seconds="3"/>
<sleep seconds="4"/>
<manifest mode="update" file="${stage.dir}/META-INF/MANIFEST.MF">
<attribute name="Class-Path" value="${classpath} ${classpath.additions}"/>
<attribute name="Bundle-SymbolicName" value="${bundlename}"/>
Expand Down
Expand Up @@ -37,7 +37,7 @@
* only if the new code is made subject to such option by the copyright
* holder.
*/
// Portions Copyright [2016-2018] [Payara Foundation and/or its affiliates]
// Portions Copyright [2016-2019] [Payara Foundation and/or its affiliates]

package org.glassfish.weld.services;

Expand All @@ -51,11 +51,12 @@
import javax.enterprise.inject.spi.AnnotatedConstructor;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.*;
import java.util.concurrent.atomic.AtomicReference;

/**
* This calls back into the ejb container to perform the around construct interception. When that's finished the
* ejb itself is then created.
* Weld object construction callback, which invokes EJB Container's interception logic.
*
*
* @param <T> instance type
*/
public class JCDIAroundConstructCallback<T> implements AroundConstructCallback<T> {
Expand All @@ -78,15 +79,10 @@ public JCDIAroundConstructCallback(BaseContainer container, EJBContextImpl ejbCo
public T aroundConstruct(final ConstructionHandle<T> handle, AnnotatedConstructor<T> constructor, Object[] parameters, Map<String, Object> data) {
this.handle = handle;
this.parameters = parameters;
T ejb;
try {
// container will end up calling createEjb() if it reaches end of interceptor chain,
// and that will set the target reference
container.intercept( LifecycleCallbackDescriptor.CallbackType.AROUND_CONSTRUCT, ejbContext );

// all the interceptors were invoked, call the constructor now
if ( target.get() == null ) {
ejb = handle.proceed( parameters, new HashMap<>() );
target.set( ejb );
}
} catch (RuntimeException e) {
throw e;
} catch (Throwable e) {
Expand All @@ -95,12 +91,16 @@ public T aroundConstruct(final ConstructionHandle<T> handle, AnnotatedConstructo
return target.get();
}

/**
* This method is invoked at end of EJB interception chain to actually construct the instance.
*/
public T createEjb() {
T instance =null;
if( null != handle ) {
instance = handle.proceed(parameters, new HashMap<>() );
}
target.set(instance);
T instance = null;
if (null != handle) {
instance = handle.proceed(parameters, new HashMap<>());
}

target.set(instance);
return instance;
}
}
Expand Up @@ -61,12 +61,8 @@
import org.jboss.weld.bean.InterceptorImpl;
import org.jboss.weld.bootstrap.WeldBootstrap;
import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive;
import org.jboss.weld.contexts.CreationalContextImpl;
import org.jboss.weld.contexts.WeldCreationalContext;
import org.jboss.weld.interceptor.proxy.InterceptionContext;
import org.jboss.weld.interceptor.spi.metadata.InterceptorClassMetadata;
import org.jboss.weld.manager.api.WeldManager;
import org.jboss.weld.util.reflection.Reflections;
import org.jvnet.hk2.annotations.Service;

import javax.annotation.PostConstruct;
Expand Down Expand Up @@ -244,7 +240,7 @@ private <T> JCDIInjectionContext<T> _createJCDIInjectionContext(EjbDescriptor ej

// JJS: 7/20/17 We must perform the around_construct interception because Weld does not know about
// interceptors defined by descriptors.
WeldCreationalContext<T> weldCreationalContext = (WeldCreationalContext) creationalContext;
WeldCreationalContext<T> weldCreationalContext = (WeldCreationalContext<T>) creationalContext;
weldCreationalContext.setConstructorInterceptionSuppressed(true);

JCDIAroundConstructCallback<T> aroundConstructCallback =
Expand All @@ -255,10 +251,6 @@ private <T> JCDIInjectionContext<T> _createJCDIInjectionContext(EjbDescriptor ej
}
T beanInstance = instance;

if( beanInstance == null ) {
// Create instance , perform constructor injection.
beanInstance = it.produce(creationalContext);
}
if (null != jcdiCtx) {
jcdiCtx.setInstance( beanInstance );
}
Expand Down Expand Up @@ -305,13 +297,12 @@ private BeanDeploymentArchive getBDAForBeanClass(BundleDescriptor bundleDesc, St
}


@SuppressWarnings("unchecked")
@Override
public <T> void injectEJBInstance(JCDIInjectionContext<T> injectionCtx) {
JCDIInjectionContextImpl<T> injectionCtxImpl = (JCDIInjectionContextImpl<T>) injectionCtx;

// Perform injection and call initializers
injectionCtxImpl.it.inject(injectionCtxImpl.instance, injectionCtxImpl.cc);
injectionCtxImpl.inject();

// NOTE : PostConstruct is handled by ejb container
}
Expand Down Expand Up @@ -359,21 +350,6 @@ private Interceptor findEjbInterceptor(Class interceptorClass, Set<EjbIntercepto
return null;
}

private <T> T getAroundConstructInterceptorInstance(Interceptor<T> interceptor, CreationalContext<T> creationalContext) {
T instance = null;

if (creationalContext instanceof CreationalContextImpl<?>) {
CreationalContextImpl<T> weldContext = Reflections.cast(creationalContext);
@SuppressWarnings("unchecked")
InterceptorImpl<T> interceptorImpl = (InterceptorImpl) interceptor;
InterceptorClassMetadata<T> interceptorClassMetadata = interceptorImpl.getInterceptorMetadata();
InterceptionContext interceptionContext = weldContext.getAroundConstructInterceptionContext();
instance = interceptionContext.getInterceptorInstance(interceptorClassMetadata);
}

return instance;
}

/**
*
* @param <T> interceptor type
Expand Down Expand Up @@ -564,7 +540,7 @@ public<T> JCDIInjectionContext<T> createEmptyJCDIInjectionContext() {
private static class JCDIInjectionContextImpl<T> implements JCDIInjectionContext<T> {
InjectionTarget<T> it;
CreationalContext<T> cc;
T instance;
private T instance;

private final List<JCDIInjectionContext<T>> dependentContexts = new ArrayList<>();
private JCDIAroundConstructCallback jcdiAroundConstructCallback;
Expand All @@ -578,9 +554,18 @@ public JCDIInjectionContextImpl(InjectionTarget<T> it, CreationalContext<T> cc,
this.instance = i;
}

void inject() {
it.inject(getInstance(), cc);
}

@Override
public T getInstance() {
if (instance == null) {
if (it == null || cc == null) {
throw new IllegalStateException("Incomplete injection context: it="+it+" cc="+cc);
}
instance = it.produce(cc);
}
return instance;
}

Expand Down Expand Up @@ -646,7 +631,7 @@ public T createEjbAfterAroundConstruct() {
if( null != jcdiAroundConstructCallback) {
setInstance( (T) jcdiAroundConstructCallback.createEjb() );
}
return instance;
return getInstance();
}

public void setJCDIAroundConstructCallback( JCDIAroundConstructCallback jcdiAroundConstructCallback ) {
Expand Down

0 comments on commit 34ad29f

Please sign in to comment.