Skip to content
This repository was archived by the owner on Nov 15, 2022. It is now read-only.

Commit 804a1c0

Browse files
ankathuryaminikb
authored andcommitted
Fixes #22150: Around construct support for GF 5.0 (#22151)
1 parent 42acfeb commit 804a1c0

7 files changed

Lines changed: 418 additions & 79 deletions

File tree

appserver/appclient/client/acc/src/main/java/org/glassfish/appclient/client/acc/ACCJCDIServiceImpl.java

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
import javax.inject.Inject;
6161
import javax.naming.NamingException;
6262
import javax.servlet.ServletContext;
63-
import java.util.Set;
63+
import java.util.*;
6464

6565
/**
6666
* @author <a href="mailto:phil.zampino@oracle.com">Phil Zampino</a>
@@ -190,10 +190,10 @@ public void injectManagedObject(Object managedObject, BundleDescriptor bundle) {
190190

191191

192192
@Override
193-
public <T> T createInterceptorInstance(Class<T> interceptorClass,
194-
BundleDescriptor bundle,
195-
JCDIService.JCDIInjectionContext ejbContext,
196-
Set<EjbInterceptor> ejbInterceptors ) {
193+
public <T> T createInterceptorInstance( Class<T> interceptorClass,
194+
EjbDescriptor ejbDesc,
195+
JCDIService.JCDIInjectionContext ejbContext,
196+
Set<EjbInterceptor> ejbInterceptors ) {
197197
T interceptorInstance = null;
198198

199199
WeldContainer wc = getWeldContainer();
@@ -215,16 +215,21 @@ public <T> T createInterceptorInstance(Class<T> interceptorClass,
215215

216216

217217
@Override
218-
public JCDIInjectionContext createJCDIInjectionContext(EjbDescriptor ejbDesc) {
219-
return createJCDIInjectionContext(ejbDesc, null);
218+
public <T> JCDIInjectionContext<T> createJCDIInjectionContext(EjbDescriptor ejbDesc, Map<Class, Object> ejbInfo) {
219+
return createJCDIInjectionContext(ejbDesc, null, null);
220220
}
221221

222222

223223
@Override
224-
public JCDIInjectionContext createJCDIInjectionContext(EjbDescriptor ejbDesc, Object instance) {
224+
public <T> JCDIInjectionContext<T> createJCDIInjectionContext(EjbDescriptor ejbDesc, T instance, Map<Class, Object> ejbInfo) {
225225
throw new UnsupportedOperationException("Application Client Container");
226226
}
227227

228+
@Override
229+
public JCDIInjectionContext createEmptyJCDIInjectionContext() {
230+
return new JCDIInjectionContextImpl();
231+
}
232+
228233

229234
@Override
230235
public void injectEJBInstance(JCDIInjectionContext injectionCtx) {
@@ -255,6 +260,9 @@ private static class JCDIInjectionContextImpl implements JCDIInjectionContext {
255260
CreationalContext cc;
256261
Object instance;
257262

263+
JCDIInjectionContextImpl() {
264+
}
265+
258266
JCDIInjectionContextImpl(InjectionTarget it, CreationalContext cc, Object i) {
259267
this.it = it;
260268
this.cc = cc;
@@ -265,6 +273,11 @@ public Object getInstance() {
265273
return instance;
266274
}
267275

276+
@Override
277+
public void setInstance(Object instance) {
278+
this.instance = instance;
279+
}
280+
268281
@SuppressWarnings("unchecked")
269282
public void cleanup(boolean callPreDestroy) {
270283

@@ -281,14 +294,35 @@ public InjectionTarget getInjectionTarget() {
281294
return it;
282295
}
283296

297+
@Override
298+
public void setInjectionTarget(InjectionTarget injectionTarget) {
299+
this.it = injectionTarget;
300+
}
301+
284302
@Override
285303
public CreationalContext getCreationalContext() {
286304
return cc;
287305
}
288306

307+
@Override
308+
public void setCreationalContext(CreationalContext creationalContext) {
309+
this.cc = creationalContext;
310+
}
311+
289312
public void addDependentContext( JCDIInjectionContext dependentContext ) {
290313
// nothing for now
291314
}
315+
316+
@Override
317+
public Collection<JCDIInjectionContext> getDependentContexts() {
318+
return new ArrayList<JCDIInjectionContext>();
319+
}
320+
321+
@Override
322+
public Object createEjbAfterAroundConstruct() {
323+
// nothing for now
324+
return null;
325+
}
292326
}
293327

294328

appserver/common/container-common/src/main/java/com/sun/enterprise/container/common/spi/JCDIService.java

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,10 @@
4848

4949
import javax.enterprise.context.spi.CreationalContext;
5050
import javax.enterprise.inject.spi.InjectionTarget;
51-
import javax.enterprise.inject.spi.Interceptor;
5251
import javax.naming.NamingException;
5352
import javax.servlet.ServletContext;
53+
import java.util.Collection;
54+
import java.util.Map;
5455
import java.util.Set;
5556

5657
/**
@@ -75,43 +76,94 @@ public <T> JCDIInjectionContext<T> createManagedObject(Class<T> managedClass, Bu
7576
/**
7677
* Create an inteceptor instance for an ejb.
7778
* @param interceptorClass The interceptor class.
78-
* @param bundle The ejb bundle.
79+
* @param ejbDesc The ejb descriptor of the ejb for which the interceptor is created.
7980
* @param ejbContext The ejb context.
8081
* @param ejbInterceptors All of the ejb interceptors for the ejb.
8182
*
8283
* @return The interceptor instance.
8384
*/
8485
<T> T createInterceptorInstance( Class<T> interceptorClass,
85-
BundleDescriptor bundle,
86+
EjbDescriptor ejbDesc,
8687
JCDIService.JCDIInjectionContext ejbContext,
8788
Set<EjbInterceptor> ejbInterceptors );
8889

89-
public <T> JCDIInjectionContext<T> createJCDIInjectionContext(EjbDescriptor ejbDesc);
90-
public <T> JCDIInjectionContext<T> createJCDIInjectionContext(EjbDescriptor ejbDesc, T instance);
90+
/**
91+
* Create an ejb via CDI.
92+
*
93+
* @param ejbDesc The ejb descriptor
94+
* @param ejbInfo Information about the ejb. Entries are the com.sun.ejb.containers.BaseContainer
95+
* and com.sun.ejb.containers.EJBContextImpl
96+
* @return The created EJB.
97+
*/
98+
<T> JCDIInjectionContext<T> createJCDIInjectionContext(EjbDescriptor ejbDesc, Map<Class, Object> ejbInfo);
99+
100+
//todo: This should be removed as it is not used.
101+
public <T> JCDIInjectionContext<T> createJCDIInjectionContext(EjbDescriptor ejbDesc, T instance, Map<Class, Object> ejbInfo);
91102

92103
public <T> void injectEJBInstance(JCDIInjectionContext<T> injectionCtx);
93104

105+
/**
106+
* Create an empty JCDIInjectionContext.
107+
* @return The empty JCDIInjectionContext.
108+
*/
109+
JCDIInjectionContext createEmptyJCDIInjectionContext();
110+
94111
public interface JCDIInjectionContext<T> {
95-
public T getInstance();
96-
public void cleanup(boolean callPreDestroy);
112+
/**
113+
* @return The instance associated with this context.
114+
*/
115+
T getInstance();
116+
117+
/**
118+
* Set the instance on this context
119+
* @param instance The instance to set.
120+
*/
121+
void setInstance( T instance );
122+
123+
void cleanup(boolean callPreDestroy);
97124

98125
/**
99126
* @return The injection target.
100127
*/
101128
InjectionTarget<T> getInjectionTarget();
102129

130+
/**
131+
* Set the injection target.
132+
* @param injectionTarget The injection target to set.
133+
*/
134+
void setInjectionTarget( InjectionTarget<T> injectionTarget );
135+
103136
/**
104137
* @return The creational context.
105138
*/
106139
CreationalContext<T> getCreationalContext();
107140

141+
/**
142+
* Set the creational context.
143+
* @param creationalContext The creational context.
144+
*/
145+
void setCreationalContext( CreationalContext<T> creationalContext );
146+
108147
/**
109148
* Add a dependent context to this context so that the dependent
110149
* context can be cleaned up when this one is.
111150
*
112151
* @param dependentContext The dependenct context.
113152
*/
114153
void addDependentContext( JCDIInjectionContext dependentContext );
154+
155+
/**
156+
* @return The dependent contexts.
157+
*/
158+
Collection<JCDIInjectionContext> getDependentContexts();
159+
160+
/**
161+
* Create the EJB and perform constructor injection, if applicable. This should only happen when the
162+
* last interceptor method in the AroundConstruct interceptor chain invokes the InvocationContext.proceed
163+
* method. If the InvocationContext.proceed method is not invoked by an interceptor method,
164+
* the target instance will not be created.
165+
*/
166+
T createEjbAfterAroundConstruct();
115167
}
116168

117169
}

appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/BaseContainer.java

Lines changed: 53 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1674,8 +1674,17 @@ protected String getJavaGlobalJndiNamePrefix() {
16741674
return javaGlobalPrefix.toString();
16751675
}
16761676

1677-
public void createEjbInstance(Object[] params, EJBContextImpl ctx) throws Exception {
1678-
Object instance = _constructEJBInstance();
1677+
// This method is used to create the ejb after the around_construct interceptor chain has completed.
1678+
public void createEjbInstanceForInterceptors(Object[] params, EJBContextImpl ctx) throws Exception {
1679+
Object instance;
1680+
EjbBundleDescriptorImpl ejbBundle = ejbDescriptor.getEjbBundleDescriptor();
1681+
if( (jcdiService != null) && jcdiService.isJCDIEnabled(ejbBundle)) {
1682+
// ejb creation for cdi is handled in JCDIServiceImpl not here.
1683+
instance = ctx.getJCDIInjectionContext().createEjbAfterAroundConstruct();
1684+
} else {
1685+
// this is only for non-cdi case.
1686+
instance = _constructEJBInstance();
1687+
}
16791688
ctx.setEJB(instance);
16801689
}
16811690

@@ -1691,9 +1700,23 @@ protected EJBContextImpl createEjbInstanceAndContext() throws Exception {
16911700
try {
16921701
ejbInv = createEjbInvocation(null, ctx);
16931702
invocationManager.preInvoke(ejbInv);
1703+
1704+
if( (jcdiService != null) && jcdiService.isJCDIEnabled(ejbBundle)) {
1705+
// In cdi we need this for the interceptors to store dependent jcdi contexts. We can't assign the
1706+
// other info as the ejb has not been created yet.
1707+
jcdiCtx = jcdiService.createEmptyJCDIInjectionContext();
1708+
ctx.setJCDIInjectionContext( jcdiCtx );
1709+
}
1710+
1711+
// Interceptors must be created before the ejb so they're available for around construct.
1712+
createEjbInterceptors( ctx, jcdiCtx );
16941713

16951714
if( (jcdiService != null) && jcdiService.isJCDIEnabled(ejbBundle)) {
1696-
jcdiCtx = jcdiService.createJCDIInjectionContext(ejbDescriptor);
1715+
HashMap<Class, Object> ejbInfo = new HashMap<>();
1716+
ejbInfo.put( BaseContainer.class, this );
1717+
ejbInfo.put( EJBContextImpl.class, ctx );
1718+
ejbInfo.put( JCDIService.JCDIInjectionContext.class, jcdiCtx );
1719+
jcdiService.createJCDIInjectionContext(ejbDescriptor, ejbInfo );
16971720
instance = jcdiCtx.getInstance();
16981721
} else {
16991722
injectEjbInstance(ctx);
@@ -1703,6 +1726,12 @@ protected EJBContextImpl createEjbInstanceAndContext() throws Exception {
17031726
success = true;
17041727

17051728
} catch (Throwable th) {
1729+
try {
1730+
if ( jcdiCtx != null ) {
1731+
// protecte against memory leak
1732+
jcdiCtx.cleanup( true );
1733+
}
1734+
} catch (Throwable ignore ) {}
17061735
throw new InvocationTargetException(th);
17071736
} finally {
17081737
try {
@@ -1720,12 +1749,9 @@ protected EJBContextImpl createEjbInstanceAndContext() throws Exception {
17201749

17211750
}
17221751

1723-
EJBContextImpl contextImpl = _constructEJBContextImpl(instance);
1724-
if( jcdiCtx != null ) {
1725-
contextImpl.setJCDIInjectionContext(jcdiCtx);
1726-
}
1752+
ctx.setEJB( instance );
17271753

1728-
return contextImpl;
1754+
return ctx;
17291755
}
17301756

17311757
protected EJBContextImpl _constructEJBContextImpl(Object instance) {
@@ -1737,16 +1763,13 @@ protected Object _constructEJBInstance() throws Exception {
17371763
return ejbClass.newInstance();
17381764
}
17391765

1740-
protected void injectEjbInstance(EJBContextImpl context) throws Exception {
1741-
1766+
private void createEjbInterceptors(EJBContextImpl context,
1767+
JCDIService.JCDIInjectionContext ejbInterceptorsJCDIInjectionContext) throws Exception {
17421768
EjbBundleDescriptorImpl ejbBundle = ejbDescriptor.getEjbBundleDescriptor();
17431769

1744-
Object[] interceptorInstances = null;
1770+
Object[] interceptorInstances;
17451771

17461772
if( (jcdiService != null) && jcdiService.isJCDIEnabled(ejbBundle)) {
1747-
1748-
jcdiService.injectEJBInstance(context.getJCDIInjectionContext());
1749-
17501773
Class[] interceptorClasses = interceptorManager.getInterceptorClasses();
17511774

17521775
interceptorInstances = new Object[interceptorClasses.length];
@@ -1756,18 +1779,14 @@ protected void injectEjbInstance(EJBContextImpl context) throws Exception {
17561779
// is still our responsibility
17571780
interceptorInstances[i] =
17581781
jcdiService.createInterceptorInstance(interceptorClasses[i],
1759-
ejbBundle,
1760-
context.getJCDIInjectionContext(),
1782+
ejbDescriptor,
1783+
ejbInterceptorsJCDIInjectionContext,
17611784
context.getContainer().getEjbDescriptor().getInterceptorClasses() );
17621785
}
17631786

17641787
interceptorManager.initializeInterceptorInstances(interceptorInstances);
17651788

17661789
} else {
1767-
if (context.getEJB() != null) {
1768-
injectionManager.injectInstance(context.getEJB(), ejbDescriptor, false);
1769-
}
1770-
17711790
interceptorInstances = interceptorManager.createInterceptorInstances();
17721791

17731792
for (Object interceptorInstance : interceptorInstances) {
@@ -1777,7 +1796,19 @@ protected void injectEjbInstance(EJBContextImpl context) throws Exception {
17771796
}
17781797

17791798
context.setInterceptorInstances(interceptorInstances);
1799+
}
17801800

1801+
protected void injectEjbInstance(EJBContextImpl context) throws Exception {
1802+
1803+
EjbBundleDescriptorImpl ejbBundle = ejbDescriptor.getEjbBundleDescriptor();
1804+
1805+
if( (jcdiService != null) && jcdiService.isJCDIEnabled(ejbBundle)) {
1806+
jcdiService.injectEJBInstance(context.getJCDIInjectionContext());
1807+
} else {
1808+
if (context.getEJB() != null) {
1809+
injectionManager.injectInstance(context.getEJB(), ejbDescriptor, false);
1810+
}
1811+
}
17811812
}
17821813

17831814
protected void cleanupInstance(EJBContextImpl context) {
@@ -2010,8 +2041,8 @@ public void preInvoke(EjbInvocation inv) {
20102041
throw new PreInvokeException(ejbEx);
20112042
}
20122043
}
2013-
2014-
protected boolean intercept(CallbackType eventType, EJBContextImpl ctx)
2044+
2045+
public boolean intercept(CallbackType eventType, EJBContextImpl ctx)
20152046
throws Throwable {
20162047

20172048
return interceptorManager.intercept(eventType, ctx);

appserver/ejb/ejb-container/src/main/java/com/sun/ejb/containers/interceptors/CallbackInvocationContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ public void invokeSpecial() throws Throwable {
219219
targetObjectInstance = targetObjectClass.newInstance();
220220
interceptorInfo.setTargetObjectInstance(targetObjectInstance);
221221
} else {
222-
container.createEjbInstance(ctorParams, ctx);
222+
container.createEjbInstanceForInterceptors(ctorParams, ctx);
223223
targetObjectInstance = ctx.getEJB();
224224
}
225225
} // else do nothing? XXX

appserver/web/weld-integration/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,11 @@
153153
<artifactId>gf-weld-connector</artifactId>
154154
<version>${project.version}</version>
155155
</dependency>
156+
<dependency>
157+
<groupId>org.glassfish.main.ejb</groupId>
158+
<artifactId>ejb-container</artifactId>
159+
<version>${project.version}</version>
160+
</dependency>
156161
<dependency>
157162
<groupId>org.osgi</groupId>
158163
<artifactId>org.osgi.core</artifactId>

0 commit comments

Comments
 (0)