EJB 3.1 @Singleton remote access
ret May 12, 2010 8:36 AMHello!
While testing the new @Singleton-Annotation almost completely implemented in JBoss AS 6 M3 i encountered several problems during deploying or getting the right Interface.
My Remote Interface:
@Remote @RemoteBinding(jndiBinding=ParameterHolder.JNDI_BINDING) public interface ParameterHolder { public static final String JNDI_BINDING = JNDI_PREFIX + "core/ParameterHolder"; public abstract void reloadAll(); /** * Methode für Interceptoren, um bestimmte Parameter * nach einem Create / Update / Delete neu zu laden * @param oid */ public abstract void reload(Parameter param); public abstract void unload(Parameter param); public abstract Parameter get(String name, Company company); }
my Local Interface:
@Local @LocalBinding(jndiBinding=ParameterHolderLocal.JNDI_BINDING) public interface ParameterHolderLocal { public static final String JNDI_BINDING = ParameterHolder.JNDI_BINDING + JNDI_SUFFIX_LOCAL; public abstract void reloadAll(); /** * Methode für Interceptoren, um bestimmte Parameter * nach einem Create / Update / Delete neu zu laden * @param oid */ public abstract void reload(Parameter param); public abstract void unload(Parameter param); public abstract Parameter get(String name, Company company); }
my BeanImplementation:
@Singleton @Startup @DependsOn(ParameterServiceLocal.JNDI_BINDING) public class ParameterHolderImpl implements ParameterHolder, ParameterHolderLocal { private static Set<Parameter> params = new HashSet<Parameter>(); private Log LOG = LogFactory.getLog(this.getClass()); @EJB(mappedName=ParameterServiceLocal.JNDI_BINDING) private ParameterServiceLocal parameterservice; @PostConstruct private void init() { params.clear(); params.addAll(parameterservice.findAll()); } @SuppressWarnings("unused") @PreDestroy private void destroy() { params.clear(); } @Lock(LockType.WRITE) public void reloadAll() { init(); } /** * Methode für Interceptoren, um bestimmte Parameter * nach einem Create / Update / Delete neu zu laden * @param oid */ @Lock(LockType.WRITE) public void reload(Parameter param) { if (param == null) { return; } if (LOG.isTraceEnabled()) { LOG.trace("reload \"" + param.getName() + "\" from Company " + param.getCompany()); } // da es sein kann, dass der Parameter neu erstellt wurde, muss er nochmal nachgeladen werden param = parameterservice.findByName(param.getName(), param.getCompany()); // wenn der param nicht null ist und entweder nicht in der Liste ist (also neu angelegt) // oder in der Liste ist und gelöscht werden konnte if (param != null && (!params.contains(param) || params.remove(param))) { params.add(param); } else { if (LOG.isWarnEnabled()) { LOG.warn("cannot reload Parameter: " + param); } } } @Lock(LockType.WRITE) public void unload(Parameter param) { if (param == null) { return; } if (LOG.isTraceEnabled()) { LOG.trace("unload \"" + param.getName() + "\" from Company " + param.getCompany()); } params.remove(param); } @Lock(LockType.READ) public Parameter get(String name, Company company) { Iterator<Parameter> iter = params.iterator(); while (iter.hasNext()) { Parameter p = iter.next(); if (p.getCompany().equals(company) && p.getName().equals(name)) { return p; } } return null; } }
At my ParameterServiceImpl i added Interceptors to the write / update / delete-Methods to renew these one Parameter in the global Cache (this Singleton)
in my serverlog this line appeared on deploying my app:
2010-05-12 13:12:08,040 WARN [org.jboss.ejb3.session.SessionContainer] (HDScanner) No JndiSessionRegistrarBase was found; byassing binding of Proxies to jboss.j2ee:service=EJB3,name=ParameterHolderImpl in Global JNDI.
(yes, its byassing instead of bypassing )
in my junittest
public class CoreServicesRemoteTest extends TestCase { private Context ctx; private CompanyService cs; private ParameterService ps; private ParameterHolder ph; protected void setUp() throws Exception { super.setUp(); ctx = new JndiConnection().getInitialContext(); assertNotNull(ctx); cs = (CompanyService) ctx.lookup(CompanyService.JNDI_BINDING); assertNotNull(cs); ps = (ParameterService) ctx.lookup(ParameterService.JNDI_BINDING); assertNotNull(ps); ph = (ParameterHolder) ctx.lookup(ParameterHolder.JNDI_BINDING); assertNotNull(ph); } public void testCompanyCreate() throws Exception { Company c = cs.create(1, "my Company"); assertNotNull(c); Parameter p = ps.create("mein Param","Wert", c); assertNotNull(ps.find(p.getOid())); assertNotNull(ph.get("mein Param", c)); assertTrue(ps.delete(p)); assertNull(ph.get("mein param", c)); assertTrue(cs.delete(c)); } }
i get an Communication-Exception at the lookup for Parameterholder:
javax.naming.CommunicationException [Root exception is java.lang.ClassNotFoundException: org.jboss.ejb3.singleton.proxy.impl.invocationhandler.SingletonBeanRemoteInvocationHandler (no security manager: RMI class loader disabled)] at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:847) at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:688) at javax.naming.InitialContext.lookup(Unknown Source) at de.neutrasoft.portal.test.CoreServicesRemoteTest.setUp(CoreServicesRemoteTest.java:28) at junit.framework.TestCase.runBare(TestCase.java:128) at junit.framework.TestResult$1.protect(TestResult.java:106) at junit.framework.TestResult.runProtected(TestResult.java:124) at junit.framework.TestResult.run(TestResult.java:109) at junit.framework.TestCase.run(TestCase.java:120) at junit.framework.TestSuite.runTest(TestSuite.java:230) at junit.framework.TestSuite.run(TestSuite.java:225) at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130) 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.lang.ClassNotFoundException: org.jboss.ejb3.singleton.proxy.impl.invocationhandler.SingletonBeanRemoteInvocationHandler (no security manager: RMI class loader disabled) at sun.rmi.server.LoaderHandler.loadClass(Unknown Source) at sun.rmi.server.LoaderHandler.loadClass(Unknown Source) at java.rmi.server.RMIClassLoader$2.loadClass(Unknown Source) at java.rmi.server.RMIClassLoader.loadClass(Unknown Source) at sun.rmi.server.MarshalInputStream.resolveClass(Unknown Source) at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source) at java.io.ObjectInputStream.readClassDesc(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.defaultReadFields(Unknown Source) at java.io.ObjectInputStream.readSerialData(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.readObject(Unknown Source) at java.rmi.MarshalledObject.get(Unknown Source) at org.jnp.interfaces.MarshalledValuePair.get(MarshalledValuePair.java:72) at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:771) ... 16 more
my second try: make ParameterHolder stateless and with static HashMap, but that fails too, i guess because the Bean is destroyed between 1st Instance + Parameter stuffed and first get-Call on the Map.
Whats the Problem here? Any Classes still missing in M3?
regards, Chris