Skip to content

Commit 159bef1

Browse files
author
ksirigeri
committed
fix for TOMEE-4560
1 parent 9c19210 commit 159bef1

File tree

2 files changed

+121
-2
lines changed

2 files changed

+121
-2
lines changed

container/openejb-core/src/main/java/org/apache/openejb/core/ivm/EjbObjectProxyHandler.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import org.apache.openejb.ApplicationException;
2121
import org.apache.openejb.BeanContext;
22+
import org.apache.openejb.ContainerType;
2223
import org.apache.openejb.InterfaceType;
2324
import org.apache.openejb.InvalidateReferenceException;
2425
import org.apache.openejb.OpenEJBException;
@@ -35,6 +36,7 @@
3536
import javax.ejb.EJBAccessException;
3637
import javax.ejb.EJBLocalObject;
3738
import javax.ejb.EJBObject;
39+
import javax.ejb.Remove;
3840
import java.io.ObjectStreamException;
3941
import java.lang.reflect.Method;
4042
import java.rmi.AccessException;
@@ -75,7 +77,7 @@ public Object _invoke(final Object p, final Class interfce, final Method m, fina
7577
if (logger.isDebugEnabled()) {
7678
logger.debug("EjbObjectProxyHandler: invoking method " + methodName + " on " + deploymentID + " with identity " + primaryKey);
7779
}
78-
Integer operation = dispatchTable.get(methodName);
80+
Integer operation = getMappedOperation(m);
7981
if (operation != null) {
8082
if (operation == 3) {
8183
if (m.getParameterTypes()[0] != EJBObject.class && m.getParameterTypes()[0] != EJBLocalObject.class) {
@@ -85,7 +87,12 @@ public Object _invoke(final Object p, final Class interfce, final Method m, fina
8587
operation = m.getParameterTypes().length == 0 ? operation : null;
8688
}
8789
}
88-
if (operation == null || !interfaceType.isComponent()) {
90+
91+
92+
boolean isComponentOperation = operation != null && interfaceType.isComponent();
93+
boolean isRemoveOperation = dispatchTable.get("remove").equals(operation) && ContainerType.STATEFUL.equals(this.container.getContainerType());
94+
95+
if (!isComponentOperation && !isRemoveOperation) {
8996
retValue = businessMethod(interfce, m, a, p);
9097
} else {
9198
switch (operation) {
@@ -174,6 +181,14 @@ public Object _invoke(final Object p, final Class interfce, final Method m, fina
174181
}
175182
}
176183

184+
private static Integer getMappedOperation(final Method m) {
185+
Integer opCode = dispatchTable.get(m.getName());
186+
if (opCode == null && m.getDeclaredAnnotation(Remove.class) != null) {
187+
opCode = dispatchTable.get("remove");
188+
}
189+
return opCode;
190+
}
191+
177192
protected Object getEJBHome(final Method method, final Object[] args, final Object proxy) throws Throwable {
178193
checkAuthorization(method);
179194
return getBeanContext().getEJBHome();
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.openejb.core.stateful;
18+
19+
import junit.framework.TestCase;
20+
import org.apache.openejb.OpenEJB;
21+
import org.apache.openejb.assembler.classic.*;
22+
import org.apache.openejb.config.ConfigurationFactory;
23+
import org.apache.openejb.core.OpenEJBInitialContextFactory;
24+
import org.apache.openejb.jee.EjbJar;
25+
import org.apache.openejb.jee.StatefulBean;
26+
27+
import javax.ejb.Remote;
28+
import javax.ejb.Remove;
29+
import javax.ejb.Stateful;
30+
import javax.naming.Context;
31+
import javax.naming.InitialContext;
32+
import java.util.concurrent.ConcurrentMap;
33+
34+
import static org.junit.Assert.assertTrue;
35+
36+
/**
37+
*
38+
* @version $Rev$ $Date$
39+
*/
40+
public class StatefulBeanRegistryCleanupTest extends TestCase {
41+
42+
@Override
43+
protected void setUp() throws Exception {
44+
System.setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY, OpenEJBInitialContextFactory.class.getName());
45+
// System.setProperty("openejb.validation.output.level" , "VERBOSE");
46+
47+
final ConfigurationFactory config = new ConfigurationFactory();
48+
final Assembler assembler = new Assembler();
49+
50+
assembler.createTransactionManager(config.configureService(TransactionServiceInfo.class));
51+
assembler.createSecurityService(config.configureService(SecurityServiceInfo.class));
52+
53+
// containers
54+
final StatefulSessionContainerInfo statefulContainerInfo = config.configureService(StatefulSessionContainerInfo.class);
55+
assembler.createContainer(statefulContainerInfo);
56+
57+
final EjbJar ejbJar = new EjbJar();
58+
ejbJar.addEnterpriseBean(new StatefulBean(MyBean.class));
59+
60+
assembler.createApplication(config.configureApplication(ejbJar));
61+
}
62+
63+
@Override
64+
protected void tearDown() throws Exception {
65+
OpenEJB.destroy();
66+
}
67+
68+
public void test() throws Exception {
69+
final Context context = new InitialContext();
70+
final MyBeanInterface myBean = (MyBeanInterface) context.lookup("MyBeanRemote");
71+
java.lang.reflect.Field hField = myBean.getClass().getSuperclass().getDeclaredField("h");
72+
hField.setAccessible(true);
73+
Object hValue = hField.get(myBean);
74+
ConcurrentMap reg = ((StatefulEjbObjectHandler) hValue).getLiveHandleRegistry();
75+
76+
myBean.cleanup();
77+
assertTrue("Live handle registry should be empty after removal", reg.isEmpty());
78+
}
79+
80+
public interface MyBeanInterface {
81+
String echo(String string);
82+
83+
@Remove
84+
void cleanup();
85+
}
86+
87+
88+
@Stateful
89+
@Remote
90+
public static class MyBean implements MyBeanInterface {
91+
92+
@Override
93+
public String echo(final String string) {
94+
final StringBuilder sb = new StringBuilder(string);
95+
return sb.reverse().toString();
96+
}
97+
98+
@Override
99+
public void cleanup() {
100+
System.out.println("cleaning up MyBean instance");
101+
}
102+
103+
}
104+
}

0 commit comments

Comments
 (0)