NameAlreadyBoundException using JNDI - java

I created a session bean with this code:
package ejb2;
import javax.annotation.Resource;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
#Stateless(name = "TestEJB", mappedName = "EJB2-Project1-TestEJB")
public class TestEJBBean implements TestEJB, TestEJBLocal {
#Resource
SessionContext sessionContext;
public TestEJBBean() {
}
public String getHello(String who_welcome) {
return "Hello " + who_welcome;
}
}
As you can see, it's almost a default code (except getHello method). Besides this bean I have a client:
package ejb2;
import java.util.Hashtable;
import javax.naming.CommunicationException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class TestEJBClient {
public static void main(String[] args) {
try {
final Context context = getInitialContext();
TestEJB testEJB = (TestEJB) context.lookup("EJB2-Project1-TestEJB#ejb2.TestEJB");
System.out.println(testEJB.getHello("Student"));
} catch (CommunicationException ex) {
System.out.println(ex.getClass().getName());
System.out.println(ex.getRootCause().getLocalizedMessage());
System.out.println("\n*** A CommunicationException was raised. This typically\n*** occurs when the target WebLogic server is not running.\n");
} catch (Exception ex) {
ex.printStackTrace();
}
}
private static Context getInitialContext() throws NamingException {
Hashtable env = new Hashtable();
// WebLogic Server 10.x/12.x connection details
env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, "t3://localhost:7101");
return new InitialContext(env);
}
}
First time it worked like a charm. But then I created another bean:
package ejb2;
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.ejb.SessionContext;
import javax.naming.Context;
import javax.naming.InitialContext;
#Stateless(name = "ClientEJB", mappedName = "EJB2-Project1-ClientEJB")
public class ClientEJBBean implements ClientEJB, ClientEJBLocal {
#Resource
SessionContext sessionContext;
TestEJB testEJB;
public ClientEJBBean() {
try {
final Context context = new InitialContext();
testEJB = (TestEJB) context.lookup("EJB2-Project1-TestEJB#ejb2.TestEJB");
} catch (Exception ex) {
ex.printStackTrace();
}
}
public String getHelloFromBean(String who) {
return testEJB.getHello(who);
}
}
And now beans aren't working. I get an error like this:
weblogic.application.ModuleException: Unable to bind Business Interface to the JNDI name: EJB2Project1WebApp_warClientEJB_Home, throw exception javax.naming.NameAlreadyBoundException: [EJB:011224]Unable to bind the interface ejb2.ClientEJB to ClientEJB. Another EJB has already bound an interface to that name.; remaining name 'EJB2-Project1-ClientEJB#ejb2'. NestedException Message is :[EJB:011224]Unable to bind the interface ejb2.ClientEJB to ClientEJB. Another EJB has already bound an interface to that name.
What's the problem with these codes?

As far as i can see you try to deploy two stateless EJBs with the same JNDI name
Try to undeploy the current application , check the JNDI tree from Admin Console
and make sure the tree does not have the JNDI name you see as duplicate.

Related

Illegal argument exception for Optaplanner project, solver config does not exist as a classpath resource in the class loader

I am getting an error when running my SpringBoot application in my solver class. I am trying to create the solver factory from an xml resource contained in the resources folder exactly like the employee rostering example for OptaPlanner but I am getting an Illegal argument exception that I can't figure out why. I tried moving the xml file into the same folder as the solver class but the same error appears. I don't know why the exception is being thrown when I am following the example code that OptaPlanner has for employee rostering ?
Below is my code for my solver class:
package com.schedule.demo.solver;
import com.schedule.demo.domain.Roster;
import com.schedule.demo.service.RosterService;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.api.solver.SolverFactory;
import org.optaplanner.core.impl.score.director.ScoreDirector;
import org.optaplanner.core.impl.score.director.ScoreDirectorFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.ApplicationScope;
#ApplicationScope
#Component
public class ScheduleSolverManager implements ApplicationRunner {
public static final String SOLVER_CONFIG = "com/schedule/demo/service/solver/scheduleSolverConfig.xml";
protected final transient Logger logger = LoggerFactory.getLogger(getClass());
private SolverFactory<Roster> rosterSolverFactory;
private ScoreDirectorFactory<Roster> rosterScoreDirectorFactory;
private ThreadPoolTaskExecutor taskExecutor;
private ConcurrentMap<Integer, Solver<Roster>> deptIdToSolverMap = new ConcurrentHashMap<>();
private RosterService rosterService;
public ScheduleSolverManager(ThreadPoolTaskExecutor taskExecutor, RosterService rosterService){
this.taskExecutor = taskExecutor;
this.rosterService = rosterService;
}
#Override
public void run(ApplicationArguments args) throws Exception {
setupRosterSolverFactory();
}
private void setupRosterSolverFactory() {
rosterSolverFactory = SolverFactory.createFromXmlResource("com/schedule/demo/service/solver/scheduleSolverConfig.xml", ScheduleSolverManager.class.getClassLoader());
rosterScoreDirectorFactory = rosterSolverFactory.buildSolver().getScoreDirectorFactory();
}
public CountDownLatch solve(Integer deptID){
final CountDownLatch solvingEndedLatch = new CountDownLatch(1);
try{
taskExecutor.execute(()->{
Solver<Roster> rosterSolver = rosterSolverFactory.buildSolver();
deptIdToSolverMap.put(deptID, rosterSolver);
rosterSolver.addEventListener(event -> {
if(event.isEveryProblemFactChangeProcessed()){
logger.info("New best solution found for deptId ({}).", deptID);
Roster newRoster = event.getNewBestSolution();
rosterService.updateShiftsOfRoster(newRoster);
}
});
Roster roster = rosterService.buildRoster(deptID);
try {
rosterSolver.solve(roster);
solvingEndedLatch.countDown();
} finally {
deptIdToSolverMap.remove(deptID);
}
});
} catch (Throwable e) {
logger.error("Error solving for deptId (" + deptID + ").", e);
}
return solvingEndedLatch;
}
public Roster getRoster(final Integer deptId){
Solver<Roster> rosterSolver = deptIdToSolverMap.get(deptId);
return rosterSolver == null ? null : rosterSolver.getBestSolution();
}
public ScoreDirector<Roster> getScoreDirector() {
return rosterScoreDirectorFactory.buildScoreDirector();
}
}
The error when run is as follows:
Caused by: java.lang.IllegalArgumentException: The solverConfigResource (com/schedule/demo/service/solver/scheduleSolverConfig.xml) does not exist as a classpath resource in the classLoader (org.springframework.boot.devtools.restart.classloader.RestartClassLoader#2302b8ed).
Use the optaplanner-spring-boot-starter. It simplifies Spring integration greatly.
Guide: https://github.com/spring-guides/getting-started-guides/pull/126
Video: https://www.youtube.com/watch?v=U2N02ReT9CI
If you don't want to use the starter, this code might fix it: SolverFactory.createFromXmlResource("com/schedule/demo/service/solver/scheduleSolverConfig.xml", Roster.class.getClassLoader()); (uses the classloader of Roster).
You have to place the solver config XML under src/main/resources in order to be able to load it as a classpath resource.
So, if you load it using the resource name com/schedule/demo/service/solver/scheduleSolverConfig.xml, then the file has to be located at
src/main/resources/com/schedule/demo/service/solver/scheduleSolverConfig.xml

EJB injection - JNDI lookup fails

So I'm starting to develop a Java EE Enterprise Application with Netbeans 8.2. It's about a shop, where you have a shopping cart and you have to store each client's session correctly.
In NetBeans I have: Shop-ejb and Shop-war.
Shop-ejb contains the following classes:
CartLocal.java
package cart;
#Local
public interface CartLocal{
}
CartBean.java
package cart;
#Stateful
#StatefulTimeout(unit = TimeUnit.MINUTES, value = 20)
public class CartBean implements CartLocal{
}
Then, Shop-war contains the following servlet:
Servlet.java
import cart.CartLocal;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
#WebServlet(name = "Servlet", urlPatterns = {"/Servlet"})
public class Servlet extends HttpServlet {
private static final String CARRITO_SESSION_KEY = "shoppingCart";
public Servlet() {
super();
}
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
CartLocal carrito = (CartLocal) request.getSession().getAttribute(CARRITO_SESSION_KEY);
try {
if (carrito == null) {
InitialContext ic = new InitialContext();
carrito = (CartLocal) ic.lookup("java:global/Shop/Shop-ejb/CartBean!cart.CartLocal");
request.getSession().setAttribute(CARRITO_SESSION_KEY, carrito);
}
} catch (NamingException ex) {
Logger.getLogger(Servlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
I'm using GlasshFish, and when I access to http://localhost:8080/Shop-war/Servlet I get the following error on the NetBeans console:
Grave: javax.naming.NamingException: Lookup failed for 'java:global/Shop/Shop-ejb/CartBean!cart.CartLocal' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: Shop]
I know the lookup is failing but I tried multiple things, without result. Hope you can help me.
You need to setup an <ejb-local-ref> tag on your web.xml:
For example:
<ejb-local-ref>
<ejb-ref-name>CartLocal</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>cat.CartLocal</local>
<ejb-link>CartLocal</ejb-link>
</ejb-local-ref>
And access via lookup:
try {
if (carrito == null) {
InitialContext ic = new InitialContext();
carrito = (CartLocal) ic.lookup("java:comp/env/CartLocal");
request.getSession().setAttribute(CARRITO_SESSION_KEY, carrito);
}
} catch (NamingException ex) {
Logger.getLogger(Servlet.class.getName()).log(Level.SEVERE, null, ex);
}

AttributeNotFoundException through JMX in Startup bean on Wildfly

Hello everyone!
I'm trying to load wildfly server's system properties through JMX in Startup bean's #PostConstruct method. It works fine on the already started server instance when deployment starts, but fails while starting with server instance bootstrapping.
Wildfly 11.0.0.CR1
Startup bean code:
package ru.wildfly.test.ejb.wildflyconsulregistrar.startup;
import ru.wildfly.test.ejb.wildflyconsulregistrar.api.ConsulRegistrar;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.inject.Inject;
#Startup
#Singleton
public class WildflyConsulRegistrarStartupBean {
#Inject
private ConsulRegistrar consulRegistrar;
#PostConstruct
public void initialize() {
registerServices();
}
private void registerServices() {
consulRegistrar.registerService("WildflyTestCluster");
}
.............
}
ConsulRegistrar code:
package ru.wildfly.test.ejb.wildflyconsulregistrar.impl;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.agent.model.NewService;
import ru.test.ejb.wildflyconsulregistrar.api.ConsulRegistrar;
import ru.wildfly.test.ejb.wildflyconsulregistrar.serversettings.api.CurrentServerNodeSettings;
import javax.annotation.PostConstruct;
import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
#Dependent
public class ConsulRegistrarImpl implements ConsulRegistrar {
...............
#Inject
private CurrentServerNodeSettings currentServerNodeSettings;
.............
#Override
public void registerService(String serviceName) {
String currentNodeName = currentServerNodeSettings.getCurrentNodeName();
........................
}
.......................
}
CurrentServerNodeSettings code:
package ru.wildfly.test.ejb.wildflyconsulregistrar.serversettings.impl;
import ru.wildfly.test.ejb.wildflyconsulregistrar.serversettings.api.CurrentServerNodeSettings;
import javax.enterprise.context.Dependent;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
#Dependent
public class CurrentServerNodeSettingsWildflyImpl implements CurrentServerNodeSettings {
....................
#Override
public String getCurrentNodeName() {
String currentNodeName = getPlatformMBeanServerAttributeValue(String.class, "jboss.as:system-property=server.name", "value");
return currentNodeName;
}
private <T> T getPlatformMBeanServerAttributeValue(Class<T> valueType, String objectName, String attributeName) {
T attributeValue = null;
try {
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
Object attributeObject = mBeanServer.getAttribute(new ObjectName(objectName), attributeName);
attributeValue = attributeObject != null ? (valueType.cast(attributeObject)) : null;
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
return attributeValue;
}
}
Error message:
Caused by: java.lang.IllegalStateException:
javax.management.AttributeNotFoundException:
"WFLYCTL0216: Management resource '[(\"system-property\" => \"server.name\")]' not found"
at ru.wildfly.test.ejb.wildflyconsulregistrar.serversettings.impl.CurrentServerNodeSettingsWildflyImpl
.getPlatformMBeanServerAttributeValue(CurrentServerNodeSettingsWildflyImpl.java:41)
I have found the same issue on jboss forum https://developer.jboss.org/message/971717#971717 , but it was unanswered.
Any suggestions?
This is a dependency problem during startup, i.e. the server name is set after your #PostConstruct method gets executed. Try to load the server name lazy when it is accessed from the application for the first time.
In Wildfly there is no generic way to enforce the sequence of deployments from the application despite the definition of module dependencies. But this won't help in your case.

Wildfly 10.x remote EJB client hangs when sending an enum value with CONNECT in the name

I've got a simple stateless EJB with a method that takes a basic enum as an argument and returns the same enum.
#Stateless
#LocalBean
public class SerialBean implements RemoteSerial {
#Override
public Whatever enumTest(Whatever type) {
return type;
}
}
Here's the simple enum:
public enum Whatever {
TEST,
CONNECT_TEST
}
And a simple client:
Properties jndiProps = new Properties();
jndiProps.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProps.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
jndiProps.put("jboss.naming.client.ejb.context", true);
try {
Context ctx = new InitialContext(jndiProps);
RemoteSerial serial = (RemoteSerial)ctx.lookup("rmi_test/rmi_ejb/SerialBean!test.RemoteSerial");
System.out.println(serial.enumTest(Whatever.TEST));
System.out.println(serial.enumTest(Whatever.CONNECT_TEST));
} catch (NamingException ex) {
ex.printStackTrace();
}
When I run this code, the client successfully connects to WildFly and returns the first result (TEST). However, the client then freezes when performing the second method call (CONNECT_TEST). No response is received.
If I change the name of CONNECT_TEST to something that doesn't have CONNECT in it, the code works. I can even change CONNECT to cONNECT and that works.
I've tried this in both 10.0 and 10.1 on Windows 7 using jdk1.8.0_102 and 121.
What could possibly be going on here?
I was unable to reproduce your results. For comparison, here's my code, in full.
Server (ejb module rmi_test):
TestEnum.java
package com.example.rmitest;
public enum TestEnum {
TEST, CONNECT_TEST
}
SerialBean.java
package com.example.rmitest;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
#Stateless
#LocalBean
public class SerialBean implements RemoteSerial {
#Override
public TestEnum enumTest(TestEnum input) {
return input;
}
}
RemoteSerial.java
package com.example.rmitest;
import javax.ejb.Remote;
#Remote
public interface RemoteSerial {
TestEnum enumTest(TestEnum input);
}
Client (standalone JSE app, with wildfly-10.1.0.Final/bin/client/jboss-client.jar on it's classpath):
Client.java
package com.example.rmitest;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class Client {
public static void main(String... args) {
RemoteSerial remoteSerial = lookupRemoteService();
System.out.println(remoteSerial.enumTest(TestEnum.TEST));
System.out.println(remoteSerial.enumTest(TestEnum.CONNECT_TEST));
}
private static RemoteSerial lookupRemoteService() {
try {
return (RemoteSerial) jndiConnect().lookup("/rmi_ejb/SerialBean!com.example.rmitest.RemoteSerial");
} catch (NamingException e) {
throw new RuntimeException("Failed to lookup a remote interface", e);
}
}
private static Context jndiConnect() {
try {
Properties properties = new Properties();
properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
properties.setProperty(Context.PROVIDER_URL, "http-remoting://localhost:8080");
properties.setProperty("jboss.naming.client.ejb.context", "true");
return new InitialContext(properties);
} catch (NamingException e) {
throw new RuntimeException("Failed to establish a connection", e);
}
}
}
And finally, my console output:
TEST
CONNECT_TEST

How to run Application Client on the GlassFish Server 4 from command line

I just started to learn EJB and I wrote a simple bean and client application. Below is a code:
Interface:
package ejb;
import javax.ejb.Remote;
#Remote
public interface MySessionRemote {
String getResult();
}
Bean:
import javax.ejb.EJB;
import javax.ejb.Stateless;
#Stateless
public class MySession implements MySessionRemote {
// #EJB
//private static MySessionRemote mySession1;
#Override
public String getResult() {
return "Bean";
}
}
Client application:
package entappclient;
import javax.naming.*;
import ejb.MySessionRemote;
import java.util.Properties;
import javax.ejb.EJB;
public class Main {
// #EJB private static MySessionRemote mySession;
public static void main(String[] args) {
// TODO code application logic here
new Main().Save();
}
public Context getContext() throws javax.naming.NamingException {
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");
return new InitialContext(props);
}
public void Save () {
//System.out.println(mySession1.getResult());
try {
Context jndiContext = getContext();
System.out.println("0");
MySessionRemote ref = ySessionRemote)jndiContext.lookup("java:global/EntAppEJB- ejb/MySession!ejb.MySessionRemote");
System.out.println("1");
System.out.println(ref.getResult());
} catch (Exception e ) {
System.out.println("Save"+e);
}
}
}
When I run it under NetBeans 8 everything works fine. The result is:
0
1
Bean
But when I try to run this from command line using : appclient - client path/EntAppClient.jar, it does not work. The result is:
0
Savejavax.naming.NamingException: Lookup failed for 'java:global/EntAppEJB-ejb/M
ySession!ejb.MySessionRemote' in SerialContext[myEnv={java.naming.factory.initia
l=com.sun.enterprise.naming.SerialInitContextFactory, org.omg.CORBA.ORBInitialHo
st=localhost, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.J
NDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Ro
ot exception is javax.naming.NamingException: ejb ref resolution error for remot
e business interfaceejb.MySessionRemote [Root exception is java.lang.ClassNotFou
ndException: ejb.MySessionRemote]]
Can anybody help me to find out why I can run this under NetBeans but it does not work from command line.
Best regards
Marcin

Categories

Resources