Devs,
Im still trying to get my stateful bean loaded for the unit test with no
success.
Last time I was missing the ejbJar.addEnterpriseBean method call at the
"protected void setUp()" method below...
.
.
.
protected void setUp() throws Exception {
super.setUp();
System.setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY,
InitContextFactory.class.getName());
ConfigurationFactory config = new ConfigurationFactory();
Assembler assembler = new Assembler();
assembler.createProxyFactory(config.configureService(ProxyFactoryInfo.class));
assembler.createTransactionManager(config.configureService(TransactionServiceInfo.class));
assembler.createSecurityService(config.configureService(SecurityServiceInfo.class));
// containers
StatefulSessionContainerInfo statefulContainerInfo =
config.configureService(StatefulSessionContainerInfo.class);
statefulContainerInfo.properties.setProperty("PoolSize", "0");
statefulContainerInfo.properties.setProperty("BulkPassivate", "1");
assembler.createContainer(statefulContainerInfo);
// Setup the descriptor information
EjbJar ejbJar = new EjbJar();
ejbJar.addEnterpriseBean(new StatefulBean(WidgetBean.class));
*//I ADDED THIS LINE FOR MY TEST*
* ejbJar.addEnterpriseBean(new StatefulBean(MyLocalBeanImpl.class));*
assembler.createApplication(config.configureApplication(ejbJar));
WidgetBean.lifecycle.clear();
expectedLifecycle = Arrays.asList(Lifecycle.values());
inTxExpectedLifecycle = new ArrayList<Lifecycle>();
for (Lifecycle lifecycle : Lifecycle.values()) {
if (!lifecycle.name().startsWith("PRE_PASSIVATE") &&
!lifecycle.name().startsWith("POST_ACTIVATE")) {
inTxExpectedLifecycle.add(lifecycle);
}
}
}
.
.
.
Now I can see that my bean is loaded. The problem is that when I try to
access the "method1", the system throws...
javax.ejb.NoSuchEJBException: Not Found
at
org.apache.openejb.core.ivm.BaseEjbProxyHandler.convertException(BaseEjbProxyHandler.java:350)
at
org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:287)
at $Proxy22.method1(Unknown Source)
at
org.apache.openejb.core.stateful.StatefulContainerTest.testConcurrentMethodCall(StatefulContainerTest.java:123)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at
org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:79)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.rmi.NoSuchObjectException: Not Found
at
org.apache.openejb.core.stateful.StatefulContainer.obtainInstance(StatefulContainer.java:688)
at
org.apache.openejb.core.stateful.StatefulContainer.businessMethod(StatefulContainer.java:542)
at
org.apache.openejb.core.stateful.StatefulContainer.invoke(StatefulContainer.java:330)
at
org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(EjbObjectProxyHandler.java:217)
at
org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke(EjbObjectProxyHandler.java:77)
at
org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:282)
... 21 more
.
.
.
I drilldown the code and I figured out that this exception is thrown when
the system tries to get the bean Instance from a "cache"
(org.apache.openejb.core.stateful.StatefulContainer, line 688)...
private Instance obtainInstance(Object primaryKey, ThreadContext
callContext) throws OpenEJBException {
if (primaryKey == null) {
throw new SystemException(new NullPointerException("Cannot
obtain an instance of the stateful session bean with a null session id"));
}
Transaction currentTransaction = getTransaction(callContext);
// Find the instance
Instance instance = checkedOutInstances.get(primaryKey);
if (instance == null) {
try {
instance = cache.checkOut(primaryKey);
} catch (OpenEJBException e) {
throw e;
} catch (Exception e) {
throw new SystemException("Unexpected load exception", e);
}
// Did we find the instance?
if (instance == null) {
/* LINE 688 */ throw new InvalidateReferenceException(new
NoSuchObjectException("Not Found"));
}
// remember instance until it is returned to the cache
checkedOutInstances.put(primaryKey, instance);
}
Do you know how can I get this bean instance?
Below, the test case class with my test method ("testConcurrentMethodCall")
tkx,
Thiago.
.
.
.
/**
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.openejb.core.stateful;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.ejb.AccessTimeout;
import javax.ejb.Local;
import javax.ejb.LocalBean;
import javax.ejb.PostActivate;
import javax.ejb.PrePassivate;
import javax.ejb.Remote;
import javax.ejb.Remove;
import javax.ejb.SessionContext;
import javax.ejb.Stateful;
import javax.naming.InitialContext;
import javax.transaction.TransactionManager;
import junit.framework.TestCase;
import org.apache.openejb.assembler.classic.Assembler;
import org.apache.openejb.assembler.classic.ProxyFactoryInfo;
import org.apache.openejb.assembler.classic.SecurityServiceInfo;
import org.apache.openejb.assembler.classic.StatefulSessionContainerInfo;
import org.apache.openejb.assembler.classic.TransactionServiceInfo;
import org.apache.openejb.config.ConfigurationFactory;
import org.apache.openejb.core.ivm.naming.InitContextFactory;
import org.apache.openejb.jee.EjbJar;
import org.apache.openejb.jee.EnvEntry;
import org.apache.openejb.jee.StatefulBean;
import org.apache.openejb.loader.SystemInstance;
/**
* @version $Revision: 941800 $ $Date: 2010-05-06 12:45:02 -0400 (Thu, 06
May 2010) $
*/
public class StatefulContainerTest extends TestCase {
private List<Lifecycle> inTxExpectedLifecycle;
private List expectedLifecycle;
public void testBusinessLocalInterface() throws Exception {
testBusinessLocalInterface(expectedLifecycle);
}
public void testBusinessLocalBeanInterface() throws Exception {
List localbeanExpectedLifecycle = new ArrayList();
localbeanExpectedLifecycle.addAll(expectedLifecycle);
// can't avoid the extra constructor call
localbeanExpectedLifecycle.add(4, Lifecycle.CONSTRUCTOR);
testBusinessLocalBeanInterface(localbeanExpectedLifecycle);
}
public void testBusinessRemoteInterfaceInTx() throws Exception {
TransactionManager transactionManager =
SystemInstance.get().getComponent(TransactionManager.class);
transactionManager.begin();
try {
testBusinessRemoteInterface(inTxExpectedLifecycle);
} finally {
transactionManager.commit();
}
}
protected void testBusinessLocalInterface(List expectedLifecycle) throws
Exception {
// Do a create...
InitialContext ctx = new InitialContext();
Object object = ctx.lookup("WidgetBeanLocal");
assertTrue("instanceof widget", object instanceof Widget);
Widget widget = (Widget) object;
// Do a business method...
Stack<Object> actual = widget.getLifecycle();
assertNotNull("lifecycle", actual);
// test app exception
try {
widget.throwAppException();
fail("Expected application exception");
} catch (SQLException e) {
assertEquals("test", e.getMessage());
}
// Do another business method...
widget.afterAppException();
// Do a remove...
widget.destroy();
// Check the lifecycle of the bean
assertEquals(StatefulContainerTest.join("\n", expectedLifecycle) ,
join("\n", WidgetBean.lifecycle));
}
public void *testConcurrentMethodCall*() throws Exception {
InitialContext ctx = new InitialContext();
Object object = ctx.lookup("MyLocalBeanImplLocal");
MyLocalBean bean = (MyLocalBean) object;
bean.method1();
}
protected void testBusinessLocalBeanInterface(List expectedLifecycle)
throws Exception {
// Do a create...
InitialContext ctx = new InitialContext();
Object object = ctx.lookup("WidgetBeanLocalBean");
assertTrue("instanceof widget", object instanceof WidgetBean);
WidgetBean widget = (WidgetBean) object;
// Do a business method...
Stack<Object> actual = widget.getLifecycle();
assertNotNull("lifecycle", actual);
// test app exception
try {
widget.throwAppException();
fail("Expected application exception");
} catch (SQLException e) {
assertEquals("test", e.getMessage());
}
// Do another business method...
widget.afterAppException();
// Do a remove...
widget.destroy();
// Check the lifecycle of the bean
assertEquals(StatefulContainerTest.join("\n", expectedLifecycle) ,
join("\n", WidgetBean.lifecycle));
}
public void testBusinessRemoteInterface() throws Exception {
testBusinessRemoteInterface(expectedLifecycle);
}
public void testBusinessLocalInterfaceInTx() throws Exception {
TransactionManager transactionManager =
SystemInstance.get().getComponent(TransactionManager.class);
transactionManager.begin();
try {
testBusinessLocalInterface(inTxExpectedLifecycle);
} finally {
transactionManager.commit();
}
}
public void testBusinessLocalBeanInterfaceInTx() throws Exception {
List localbeanExpectedLifecycle = new ArrayList();
localbeanExpectedLifecycle.addAll(inTxExpectedLifecycle);
// can't avoid the extra constructor call
localbeanExpectedLifecycle.add(3, Lifecycle.CONSTRUCTOR);
TransactionManager transactionManager =
SystemInstance.get().getComponent(TransactionManager.class);
transactionManager.begin();
try {
testBusinessLocalBeanInterface(localbeanExpectedLifecycle);
} finally {
transactionManager.commit();
}
}
protected void testBusinessRemoteInterface(List expectedLifecycle)
throws Exception {
WidgetBean.lifecycle.clear();
// Do a create...
InitialContext ctx = new InitialContext();
Object object = ctx.lookup("WidgetBeanRemote");
assertTrue("instanceof widget", object instanceof RemoteWidget);
RemoteWidget widget = (RemoteWidget) object;
// Do a business method...
Stack<Object> lifecycle = widget.getLifecycle();
assertNotNull("lifecycle",lifecycle);
assertNotSame("is copy", lifecycle, WidgetBean.lifecycle);
// test app exception
try {
widget.throwAppException();
fail("Expected application exception");
} catch (SQLException e) {
assertEquals("test", e.getMessage());
}
// Do another business method...
widget.afterAppException();
// Do a remove...
widget.destroy();
try {
widget.destroy();
fail("Calling a removed bean should not be possible");
} catch (Exception e) {
}
// Check the lifecycle of the bean
assertEquals(StatefulContainerTest.join("\n", expectedLifecycle) ,
join("\n", WidgetBean.lifecycle));
}
protected void setUp() throws Exception {
super.setUp();
System.setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY,
InitContextFactory.class.getName());
ConfigurationFactory config = new ConfigurationFactory();
Assembler assembler = new Assembler();
assembler.createProxyFactory(config.configureService(ProxyFactoryInfo.class));
assembler.createTransactionManager(config.configureService(TransactionServiceInfo.class));
assembler.createSecurityService(config.configureService(SecurityServiceInfo.class));
// containers
StatefulSessionContainerInfo statefulContainerInfo =
config.configureService(StatefulSessionContainerInfo.class);
statefulContainerInfo.properties.setProperty("PoolSize", "0");
statefulContainerInfo.properties.setProperty("BulkPassivate", "1");
assembler.createContainer(statefulContainerInfo);
// Setup the descriptor information
EjbJar ejbJar = new EjbJar();
ejbJar.addEnterpriseBean(new StatefulBean(WidgetBean.class));
* StatefulBean bean = ejbJar.addEnterpriseBean(new
StatefulBean(MyLocalBeanImpl.class));*
assembler.createApplication(config.configureApplication(ejbJar));
WidgetBean.lifecycle.clear();
expectedLifecycle = Arrays.asList(Lifecycle.values());
inTxExpectedLifecycle = new ArrayList<Lifecycle>();
for (Lifecycle lifecycle : Lifecycle.values()) {
if (!lifecycle.name().startsWith("PRE_PASSIVATE") &&
!lifecycle.name().startsWith("POST_ACTIVATE")) {
inTxExpectedLifecycle.add(lifecycle);
}
}
}
private static String join(String delimeter, List items){
StringBuffer sb = new StringBuffer();
for (Object item : items) {
sb.append(item.toString()).append(delimeter);
}
return sb.toString();
}
* @Local*
* public static interface MyLocalBean {*
* **void method1();*
* **void method2();*
* }*
*
*
* *...@stateful*
* *...@accesstimeout(value = 1, unit = TimeUnit.MINUTES)*
* **public static class MyLocalBeanImpl implements MyLocalBean {*
* *...@resource(name = "mysession")*
* **private SessionContext context;*
*
*
* **public void method1() {*
* **System.out.println("Method 1 invoked!");*
* **context.getBusinessObject(MyLocalBean.class).method2();*
* **}*
*
*
* **public void method2() {*
* **System.out.println("Method 2 invoked!");*
* **}*
* **}*
@Local
public static interface Widget {
Stack<Object> getLifecycle();
void throwAppException() throws SQLException;
void afterAppException();
void destroy();
}
@Remote
public static interface RemoteWidget extends Widget {
}
public static enum Lifecycle {
// construction
CONSTRUCTOR, INJECTION, POST_CONSTRUCT, PRE_PASSIVATE1,
// business method
POST_ACTIVATE1, BUSINESS_METHOD, PRE_PASSIVATE2,
// throw app exception
POST_ACTIVATE2, PRE_PASSIVATE3,
// business method after app exception
POST_ACTIVATE3, PRE_PASSIVATE4,
// remove
POST_ACTIVATE4, REMOVE, PRE_DESTROY,
}
@LocalBean
public static class WidgetBean implements Widget, RemoteWidget {
private int activates = 0;
private int passivates = 0;
public static Stack<Object> lifecycle = new Stack<Object>();
public WidgetBean() {
lifecycle.push(Lifecycle.CONSTRUCTOR);
}
public void throwAppException() throws SQLException {
throw new SQLException("test");
}
public void afterAppException() {
}
@Resource
public void setContext(SessionContext context){
lifecycle.push(Lifecycle.INJECTION);
}
public Stack<Object> getLifecycle() {
lifecycle.push(Lifecycle.BUSINESS_METHOD);
return lifecycle;
}
@PostActivate
public void activate(){
String name = "POST_ACTIVATE" + (++activates);
try {
lifecycle.push(Enum.valueOf(Lifecycle.class, name));
} catch (Exception e) {
lifecycle.push(name);
}
}
@PrePassivate
public void passivate(){
String name = "PRE_PASSIVATE" + (++passivates);
try {
lifecycle.push(Enum.valueOf(Lifecycle.class, name));
} catch (Exception e) {
lifecycle.push(name);
}
}
@PostConstruct
public void init() {
lifecycle.push(Lifecycle.POST_CONSTRUCT);
}
@PreDestroy
public void predestroy() {
lifecycle.push(Lifecycle.PRE_DESTROY);
}
@Remove
public void destroy() {
lifecycle.push(Lifecycle.REMOVE);
}
}
}