Wildfly 13 and EJB 2.1 compatibility issue and RelativeContext Classcast issue - java

Can anyone help to solve the below issue:
I am trying to upgrade my application server from JBOSS 6 to Wildfly 12/13.
My Application is EJB based. When i am using Jboss 6, I was using Jdk 1.7
Now for Wildfly, I'm using jdk 1.8.
And, while upgrading to Wildfly, previous jndi settings wasn't working so I updated jndi configurations from
configurations file:
INITIAL_CONTEXT_FACTORY = org.jnp.interfaces.NamingContextFactory
PROVIDER_URL = jnp://localhost:1099
URL_PKG_PREFIXES = org.jboss.naming:org.jnp.interfaces
JNDI_VOOR_DS=java:/VOORSDB
to:
INITIAL_CONTEXT_FACTORY = org.wildfly.naming.client.WildFlyInitialContextFactory
PROVIDER_URL = remote+http://localhost:8080
URL_PKG_PREFIXES = org.jboss.ejb.client.naming
JNDI_VOOR_DS=java:/VOORSDB
Now i am getting error as:
ERROR [com.aithent.voor.service.ServiceLocator] (ServerService ThreadPool -- 79) Exception whichle retrieving the home object for the EJB :UserServiceEJB
ERROR [com.aithent.voor.service.ServiceLocator] (ServerService Thread Pool -- 79) org.wildfly.naming.client.store.RelativeContext cannot be cast to javax.ejb.EJBHome
ERROR [com.aithent.voor.service.ServiceFactory] (ServerService Thread Pool -- 79) java.lang.ClassCastException: org.wildfly.naming.client.store.RelativeContext cannot be cast to javax.ejb.EJBHome
This is my ServiceLocator class:
private ServiceLocator() throws Exception{
createContext();
}
public void createContext() throws Exception{
Hashtable env = new Hashtable();
cachedObject=new HashMap(10,0.8f);
env.put(Context.INITIAL_CONTEXT_FACTORY, ConfigurationManager.getInstance().getPropertyValue(WebConstants.INITIAL_CONTEXT_FACTORY));
System.out.println(ConfigurationManager.getInstance().getPropertyValue(WebConstants.INITIAL_CONTEXT_FACTORY));
env.put(Context.PROVIDER_URL, ConfigurationManager.getInstance().getPropertyValue(WebConstants.PROVIDER_URL));
env.put(Context.URL_PKG_PREFIXES, ConfigurationManager.getInstance().getPropertyValue(WebConstants.URL_PKG_PREFIXES));
env.put("jboss.naming.client.ejb.context", true);
context = new WildFlyInitialContext(env);
System.out.println("context: "+context);
log.debug("ServiceLocator createContext method ends ");
}
public EJBHome getHome(String ejbName) throws Exception{
EJBHome ejbHome = null;
log.debug("ServiceLocator getHome() starts ");
try{
System.out.println("Context: "+context);
if(context != null){
Object home = context.lookup("ejb:/"+ejbName);
System.out.println(home);
ejbHome = (EJBHome) home;
System.out.println(ejbHome);
}
}catch(Exception e){
log.error("Exception whichle retrieving the home object for the EJB : " + ejbName);
log.error(e.getMessage());
throw new Exception(e);
}
log.debug("ServiceLocator getHome() ends ");
return ejbHome;
}
I even added jboss-client from wildfly-13 - bin/client folder. I tried almost everyway posted in other Q&A's but nothing worked.
I didn't understand how to attach files, if anyone guide me, i will attach server.log and standalone-full.xml for review.
Thanks for help in advance!

I was facing the same issue on a basic HelloWorld project for EJB.
I am using wildfly 14.0.1.
It magically started working when I removed the "ejb:" from the JNDI string "ejb:ejbsample-1.0-SNAPSHOT/HelloWorld!com.ejbsample.HelloWorld"
If it would help please check the server and client code.

Related

remote connection dropped after some time in wildfly

I am using remote connection in java applet using the following code.
Hashtable jndiProps = new Hashtable<Object,Object>();
jndiProps.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProps.put(Context.PROVIDER_URL, "http-remoting://" + myhost + ":" + "8080");
jndiProps.put("jboss.naming.client.ejb.context", true);
jndiProps.put("org.jboss.ejb.client.scoped.context", true);;
//jndiProps.put(Context.URL_PKG_PREFIXES,"org.jboss.ejb.client.naming");
jndiProps.put("endpoint.name", "client-endpoint");
jndiProps.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", false);
jndiProps.put("remote.connections", "default");
jndiProps.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", false);
jndiProps.put("remote.connection.default.host", myhost);
jndiProps.put("remote.connection.default.port", "8080");
jndiProps.put(Context.SECURITY_PRINCIPAL, "demouser");
jndiProps.put(Context.SECURITY_CREDENTIALS, "demouser123");
InitialContext ctx = null;
try {
ctx = new InitialContext(jndiProps);
} catch(NamingException nex) {
nex.printStackTrace();
} catch(Exception ex) {
ex.printStackTrace();
}
RemoteInterface remote = (RemoteInterface)ctx.lookup(ejbUrl);
Here the SECURITY_PRINCIPAL is created using the add-user.sh script. The the applet loads, everything works well. But after sometime in java console , a message appears saying
Jul 13, 2016 3:04:21 PM org.jboss.ejb.client.remoting.ChannelAssociation$ResponseReceiver handleEnd
INFO: EJBCLIENT000016: Channel Channel ID 98a848d6 (outbound) of Remoting connection 22d8b2a8 to cms8sf.cdotd.ernet.in/192.168.5.240:8080 can no longer process messages.
And after that , whenever I try to access any method of remote bean Exception in thrown.
java.lang.IllegalStateException: EJBCLIENT000025: No EJB receiver available for handling [appName:app, moduleName:app-ejb, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext#490f0e4e
at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:774)
I am quite unsure why this is happening. Can someone please help me. Thank in advance.
I am using java 1.8 and wildfly 9.0.2.
Perhaps, this option will help you
remote.connection.default.connect.options.org.jboss.remoting3.RemotingOptions.HEARTBEAT_INTERVAL=5000
it's some kind of a ping

Connecting WAS to JRules USING ejb

I am trying to call RES server (v 7.1) from EAR deployed on WAS (8.5) instance. I was able to invoke rule server from standalone program and its working without any problems.
However my main problem is to invoke EJB deployed on RES server remotely from another EAR deployed on some other WAS instance. In this case we are not able to look-up the EJB remotely.
As per below thread we should bypass the EJB3 IlrSessionFactory API and should use Java EJB API to look up rule sessions directly.
http://www-01.ibm.com/support/docview.wss?uid=swg21586621
Recommendation from IBM is to use standard java api for ejb lookup or to upgrade to Rule Server 7.5 (latest 8.x).
Code snippet
// Initialization
Map<String, Object> outputParms = null;
IlrStatelessSession session=null;
IlrSessionResponse response=null;
// IlrSessionFactory factory = getFactory();
try {
sessionFactory = JRulesInvoker.getFactory();
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
env.put(Context.PROVIDER_URL,"corbaloc:iiop:localhost:28004");
Context ctx = new InitialContext(env);
Object lookupResult = ctx.lookup("ilog.rules.res.session.impl.ejb3.IlrStatelessSessionRemote");
PortableRemoteObject aPortableRemoteObject = new PortableRemoteObject();
session = (IlrStatelessSession) aPortableRemoteObject.narrow(lookupResult, IlrStatelessSession.class);
IlrPath path = new IlrPath(ruleApp, ruleSet);
IlrSessionRequest request = sessionFactory.createRequest();
request.setRulesetPath(path);
request.setInputParameters(inputParms);
request.getTraceFilter().setInfoTotalRulesFired(true);
request.getTraceFilter().setInfoExecutionEvents(true);
request.setTraceEnabled(true);
// session = sessionFactory.createStatelessSession();
System.out.println("created session " + IlrJNDIConstants.STATELESS_SESSION_EJB3_NAME);
response = session.execute(request);
System.out.println(response.getRulesetExecutionTrace().getTotalRulesFired() + " rule(s) fired.");
System.out.println("Execution output=" + response.getRulesetExecutionOutput());
// Return the result(s)
outputParms = response.getOutputParameters();
if (logger.isEnabledFor(Level.DEBUG)) {
if (response.getRulesetExecutionOutput() != null) {
logger.debug("RuleSet execution output: \n" + response.getRulesetExecutionOutput());
}
}
}catch (IlrSessionCreationException cx) {
if (logger.isEnabledFor(Level.ERROR)) {
logger.error(cx.getMessage(), cx);
}
} catch (IlrSessionException e) {
if (logger.isEnabledFor(Level.ERROR)) {
logger.error(e.getMessage(), e);
}
} catch (NamingException e) {
if (logger.isEnabledFor(Level.ERROR)) {
logger.error(e.getMessage(), e);
}
}
Error
Context: idewas/nodes/ide/servers/server1, name: ilog.rules.res.session.impl.ejb3.IlrStatelessSessionRemote: First component in name ilog.rules.res.session.impl.ejb3.IlrStatelessSessionRemote not found.
javax.naming.NameNotFoundException: Context: idewas/nodes/ide/servers/server1, name: ilog.rules.res.session.impl.ejb3.IlrStatelessSessionRemote: First component in name ilog.rules.res.session.impl.ejb3.IlrStatelessSessionRemote not found. [Root exception is org.omg.CosNaming.NamingContextPackage.NotFound: IDL:omg.org/CosNaming/NamingContext/NotFound:1.0]
at com.ibm.ws.naming.jndicos.CNContextImpl.mapNotFoundException(CNContextImpl.java:4563)
at com.ibm.ws.naming.jndicos.CNContextImpl.doLookup(CNContextImpl.java:1821)
at com.ibm.ws.naming.jndicos.CNContextImpl.doLookup(CNContextImpl.java:1776)
at com.ibm.ws.naming.jndicos.CNContextImpl.lookupExt(CNContextImpl.java:1433)
at com.ibm.ws.naming.jndicos.CNContextImpl.lookup(CNContextImpl.java:615)
at com.ibm.ws.naming.util.WsnInitCtx.lookup(WsnInitCtx.java:165)
at com.ibm.ws.naming.util.WsnInitCtx.lookup(WsnInitCtx.java:179)
at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:161)
at javax.naming.InitialContext.lookup(InitialContext.java:436)
Check in the SystemOut.log of the RES server what are the binding names for EJBs as it looks like there is no ilog.rules.res.session.impl.ejb3.IlrStatelessSessionRemote there. Also if you have two servers on the same host under the same name e.g. server1 you may have interoberability issues and need to set JVM property com.ibm.websphere.orb.uniqueServerName to true. For more details check the following page Application access problems

Error in ConnectionFactory in rabbitmq

I used RabbitMQ in my java application . I used amqp-client3.1.3.jar. But getting java.lang.NoClassDefFoundError: com/rabbitmq/client/ConnectionFactory while deploying my code in jboss. How to resolve?
public class Exapmle {
static Connection connection = null;
static Channel channel = null;
static ConnectionFactory factory = null;
private Example() {
try {
factory = new ConnectionFactory();
//--code goes here---//
}
I had written the same code in ejb which is scheduled and deployed in wildfly. I saw the resolution of adding the dependency to jboss setup. How should i do this?

Easy way to start a standalone JNDI server (and register some resources)

For testing purposes, I'm looking for a simple way to start a standalone JNDI server, and bind my javax.sql.DataSource to "java:/comp/env/jdbc/mydatasource" programmatically.
The server should bind itself to some URL, for example: "java.naming.provider.url=jnp://localhost:1099" (doesn't have to be JNP), so that I can look up my datasource from another process. I don't care about which JNDI server implementation I'll have to use (but I don't want to start a full-blown JavaEE server).
This should be so easy, but to my surprise, I couldn't find any (working) tutorial.
The JDK contains a JNDI provider for the RMI registry. That means you can use the RMI registry as a JNDI server. So, just start rmiregistry, set java.naming.factory.initial to com.sun.jndi.rmi.registry.RegistryContextFactory, and you're away.
The RMI registry has a flat namespace, so you won't be able to bind to java:/comp/env/jdbc/mydatasource, but you will be able to bind to something so it will accept java:/comp/env/jdbc/mydatasource, but will treat it as a single-component name (thanks, #EJP).
I've written a small application to demonstrate how to do this: https://bitbucket.org/twic/jndiserver/src
I still have no idea how the JNP server is supposed to work.
I worked on the John´s code and now is working good.
In this version I'm using libs of JBoss5.1.0.GA, see jar list below:
jboss-5.1.0.GA\client\jbossall-client.jar
jboss-5.1.0.GA\server\minimal\lib\jnpserver.jar
jboss-5.1.0.GA\server\minimal\lib\log4j.jar
jboss-remote-naming-1.0.1.Final.jar (downloaded from http://search.maven.com)
This is the new code:
import java.net.InetAddress;
import java.util.Hashtable;
import java.util.concurrent.Callable;
import javax.naming.Context;
import javax.naming.InitialContext;
import org.jnp.server.Main;
import org.jnp.server.NamingBeanImpl;
public class StandaloneJNDIServer implements Callable<Object> {
public Object call() throws Exception {
setup();
return null;
}
#SuppressWarnings("unchecked")
private void setup() throws Exception {
//configure the initial factory
//**in John´s code we did not have this**
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
//start the naming info bean
final NamingBeanImpl _naming = new NamingBeanImpl();
_naming.start();
//start the jnp serve
final Main _server = new Main();
_server.setNamingInfo(_naming);
_server.setPort(5400);
_server.setBindAddress(InetAddress.getLocalHost().getHostName());
_server.start();
//configure the environment for initial context
final Hashtable _properties = new Hashtable();
_properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
_properties.put(Context.PROVIDER_URL, "jnp://10.10.10.200:5400");
//bind a name
final Context _context = new InitialContext(_properties);
_context.bind("jdbc", "myJDBC");
}
public static void main(String...args){
try{
new StandaloneJNDIServer().call();
}catch(Exception _e){
_e.printStackTrace();
}
}
}
To have good logging, use this log4j properties:
log4j.rootLogger=TRACE, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
To consume the Standalone JNDI server, use this client class:
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
/**
*
* #author fabiojm - Fábio José de Moraes
*
*/
public class Lookup {
public Lookup(){
}
#SuppressWarnings("unchecked")
public static void main(String[] args) {
final Hashtable _properties = new Hashtable();
_properties.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
_properties.put("java.naming.provider.url", "jnp://10.10.10.200:5400");
try{
final Context _context = new InitialContext(_properties);
System.out.println(_context);
System.out.println(_context.lookup("java:comp"));
System.out.println(_context.lookup("java:jdbc"));
}catch(Exception _e){
_e.printStackTrace();
}
}
}
Here's a code snippet adapted from JBoss remoting samples. The code that is
in the samples (version 2.5.4.SP2 ) no longer works. While the fix
is simple it took me more hours than I want to think about to figure it out.
Sigh. Anyway, maybe someone can benefit.
package org.jboss.remoting.samples.detection.jndi.custom;
import java.net.InetAddress;
import java.util.concurrent.Callable;
import org.jnp.server.Main;
import org.jnp.server.NamingBeanImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class StandaloneJNDIServer implements Callable<Object> {
private static Logger logger = LoggerFactory.getLogger( StandaloneJNDIServer.class );
// Default locator values - command line args can override transport and port
private static String transport = "socket";
private static String host = "localhost";
private static int port = 5400;
private int detectorPort = 5400;
public StandaloneJNDIServer() {}
#Override
public Object call() throws Exception {
StandaloneJNDIServer.println("Starting JNDI server... to stop this server, kill it manually via Control-C");
//StandaloneJNDIServer server = new StandaloneJNDIServer();
try {
this.setupJNDIServer();
// wait forever, let the user kill us at any point (at which point, the client will detect we went down)
while(true) {
Thread.sleep(1000);
}
}
catch(Exception e) {
e.printStackTrace();
}
StandaloneJNDIServer.println("Stopping JBoss/Remoting server");
return null;
}
private void setupJNDIServer() throws Exception
{
// start JNDI server
String detectorHost = InetAddress.getLocalHost().getHostName();
Main JNDIServer = new Main();
// Next two lines add a naming implemention into
// the server object that handles requests. Without this you get a nice NPE.
NamingBeanImpl namingInfo = new NamingBeanImpl();
namingInfo.start();
JNDIServer.setNamingInfo( namingInfo );
JNDIServer.setPort( detectorPort );
JNDIServer.setBindAddress(detectorHost);
JNDIServer.start();
System.out.println("Started JNDI server on " + detectorHost + ":" + detectorPort );
}
/**
* Outputs a message to stdout.
*
* #param msg the message to output
*/
public static void println(String msg)
{
System.out.println(new java.util.Date() + ": [SERVER]: " + msg);
}
}
I know I'm late to the party, but I ended up hacking this together like so
InitialContext ctx = new InitialContext();
// check if we have a JNDI binding for "jdbc". If we do not, we are
// running locally (i.e. through JUnit, etc)
boolean isJndiBound = true;
try {
ctx.lookup("jdbc");
} catch(NameNotFoundException ex) {
isJndiBound = false;
}
if(!isJndiBound) {
// Create the "jdbc" sub-context (i.e. the directory)
ctx.createSubcontext("jdbc");
//parse the jetty-web.xml file
Map<String, DataSource> dataSourceProperties = JettyWebParser.parse();
//add the data sources to the sub-context
for(String key : dataSourceProperties.keySet()) {
DataSource ds = dataSourceProperties.get(key);
ctx.bind(key, ds);
}
}
Have you considered using Mocks? If I recall correctly you use Interfaces to interact with JNDI. I know I've mocked them out at least once before.
As a fallback, you could probably use Tomcat. It's not a full blown J2EE impl, it starts fast, and is fairly easy to configure JNDI resources for. DataSource setup is well documented. It's sub-optimal, but should work.
You imply you've found non-working tutorials; that may mean you've already seen these:
J2EE or J2SE? JNDI works with both
Standalone JNDI server using jnpserver.jar
I had a quick go, but couldn't get this working. A little more perseverance might do it, though.
For local, one process standalone jar purpouses I would use spring-test package:
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
SQLServerConnectionPoolDataSource myDS = new SQLServerConnectionPoolDataSource();
//setup...
builder.bind("java:comp/env/jdbc/myDS", myDS);
builder.activate();
startup log:
22:33:41.607 [main] INFO org.springframework.mock.jndi.SimpleNamingContextBuilder - Static JNDI binding: [java:comp/env/jdbc/myDS] = [SQLServerConnectionPoolDataSource:1]
22:33:41.615 [main] INFO org.springframework.mock.jndi.SimpleNamingContextBuilder - Activating simple JNDI environment
I have been looking for a similar simple starter solution recently. The "file system service provider from Sun Microsystems" has worked for me well. See https://docs.oracle.com/javase/jndi/tutorial/basics/prepare/initial.html.
The problem with the RMI registry is that you need a viewer - here you just need to look at file contents.
You may need fscontext-4.2.jar - I obtained it from http://www.java2s.com/Code/Jar/f/Downloadfscontext42jar.htm

Obtaining Context from an embedded Glassfish 3.1

Does anyone now a way to obtain server Context using Embeddable API (using org.glassfish.embeddable.GlassFish, not javax.ejb.embeddable.EJBContainer)?
It would be possible if there's a way to obtain EJBContainer from a running Glassfish, but I can't find even the list of services available for lookup.
Here's a workaround - we can obtain InitialContext as an external client.
For the full explanation check EJB_FAQ . This way at least remote EJBs could be tested:
So the full example will look like:
//Start GF
GlassFishRuntime gfRuntime = GlassFishRuntime.bootstrap();
GlassFish gf = gfRuntime.newGlassFish();
gf.start();
//Deploy application with EJBs
Deployer deployer = gf.getService(Deployer.class);
String deployedApp = deployer.deploy(new File(...), "--force=true");
//Create InitialContext
Properties props = new Properties();
props.setProperty("java.naming.factory.initial",
"com.sun.enterprise.naming.SerialInitContextFactory");
props.setProperty("java.naming.factory.url.pkgs",
"com.sun.enterprise.naming");
props.setProperty("java.naming.factory.state",
"com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
props.setProperty("org.omg.CORBA.ORBInitialHost", "localhost");
props.setProperty("org.omg.CORBA.ORBInitialPort", "3700");
InitialContext ic = new InitialContext(props);
//Lookup EJBs
ic.lookup(...)
//Stop GF
gf.stop();
gfRuntime.shutdown();
//CORBA stuck thread, have to kill it manually
System.exit(0);
Note there's a System.exit(0) at the end - com.sun.corba.ee.impl.javax.rmi.CORBA.Util.KeepAlive thread is running even after the server stop preventing JVM from stopping...
As far as I know, you can initialize the InitialContext class to obtain a context, that can further be used to perform the lookup. This was tested, and found to work in the context of looking up an EJB, deployed in the embedded container. The EJB was not configured to allow access to specific roles, in which case the com.sun.appserv.security.ProgrammaticLogin class (not exposed via the Embeddable EJB API) might help; this was not tested, but is the recommended way to initialize the Principal for the thread accessing an EJB.
A more or less complete example that runs from Maven and uses the embedded Glassfish dependency in a POM (not reproduced here, for brevity) follows:
The EJB interface:
public interface EchoManager
{
String echo(String message);
}
The Session Bean:
#Local(EchoManager.class)
#Stateless
#EJB(name="java:global/glassfish-ejb-validation/EchoManager",beanInterface=EchoManager.class)
public class EchoManagerBean implements EchoManager
{
public String echo(String message)
{
return message;
}
}
The unit test:
public class EchoManagerTest
{
#Rule
public TestName testMethod = new TestName();
private static final Logger logger = Logger.getLogger(EchoManagerTest.class.getName());
#Test
public void testEchoWithGlassfishRuntime() throws Exception
{
logger.info("Starting execution of test" + testMethod.getMethodName());
GlassFish glassFish = null;
Deployer deployer = null;
String appName = null;
try
{
//Setup
BootstrapProperties bootstrapProps = new BootstrapProperties();
GlassFishRuntime glassFishRuntime = GlassFishRuntime.bootstrap(bootstrapProps);
GlassFishProperties gfProps = new GlassFishProperties();
glassFish = glassFishRuntime.newGlassFish(gfProps);
glassFish.start();
deployer = glassFish.getDeployer();
ScatteredArchive archive = new ScatteredArchive("glassfish-ejb-validation", Type.JAR);
archive.addClassPath(new File("target", "classes"));
archive.addClassPath(new File("target", "test-classes"));
appName = deployer.deploy(archive.toURI(), "--force=true");
// Setup the context
InitialContext context = new InitialContext();
//Execute (after lookup the EJB from the context)
EchoManager manager = (EchoManager) context.lookup("java:global/glassfish-ejb-validation/EchoManager");
String echo = manager.echo("Hello World");
//Verify
assertEquals("Hello World", echo);
}
finally
{
if(deployer != null && appName != null)
{
deployer.undeploy(appName);
}
if(glassFish != null)
{
glassFish.stop();
glassFish.dispose();
}
logger.info("Ending execution of test" + testMethod.getMethodName());
}
}
}
Note that the EJB is deployed with a explicit portable JNDI name (via the #EJB annotation), as I have other tests that use the public embeddable EJB API in other tests, and it is more or less difficult to specify an application name in such tests; each test execution might result in a different JNDI name for the EJB, thus necessitating an explicit JNDI name to be specified.

Categories