The problem is not the method call, but the "SessionContext" injection. Commenting out the injection related code, the method1 call works fine. What am I missing to get the sessionContext object? tkx, Thiago.
On Wed, Jun 2, 2010 at 1:23 PM, Thiago Veronezi <[email protected]> wrote: > 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); > } > } > } > > >
