I'm creating a simple client-server Java EE application with EJB, using IntelliJ IDEA 2016 and WildFly 10.
I've created a new Java EE Project EJB_final_test and added two modules:
Java module EJB_test_client
EJB module EJB_test_server
Then I set artifact as Java EE Application Archive which creates an EJBTestEAR.ear file for EJB_test_server module.
I've deployed this EAR file on WildFly server. Server runs well and it successfully deploys the artifact on start up.
Here is my jboss-ejb-client.properties file:
remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port=8180
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT=false
Here is my code for only class ClientTest in EJB_test_client module:
package test;
import facade.TestFacadeBeanRemote;
import javax.naming.Context;
import javax.naming.InitialContext;
import java.util.Properties;
public class ClientTest {
public static void main(String[] args) throws Exception {
Properties jndiProperties = new Properties();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
Context ctx = new InitialContext(jndiProperties);
TestFacadeBeanRemote remote = (TestFacadeBeanRemote) ctx.lookup("ejb:EJBTestEAR/EJB_test_server//TestFacadeBean!facade.TestFacadeBeanRemote");
System.out.println(remote.tstPlus("Hello", "World"));
}
}
Here is code for classes TextExecutiveBean, TestFacadeBean, TestFacadeBeanRemote which are all in module EJB_test_server:
TestExecutiveBean class:
package executive;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
#Stateless
#LocalBean
public class TestExecutiveBean {
public String doPlusOperation(String str1, String str2) {
return str1 + " " + str2 + " " + str1;
}
}
TestFacadeBean class:
package facade;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import executive.TestExecutiveBean;
#Stateless
public class TestFacadeBean implements TestFacadeBeanRemote {
#EJB
private TestExecutiveBean test2;
public String tstPlus(String str1, String str2) {
return test2.doPlusOperation(str1, str2);
}
}
TestFacadeBeanRemote interface:
package facade;
import javax.ejb.Remote;
#Remote
public interface TestFacadeBeanRemote {
public String tstPlus(String str1, String str2);
}
When I'm trying to run ClientTest main method, which tries to communicate with server for finding tstPlus() method in EJBTestEAR, I'm getting the following exception:
Exception in thread "main" java.lang.IllegalStateException:
EJBCLIENT000025: No EJB receiver available for handling
[appName:EJBTestEAR, moduleName:EJB_test_server, distinctName:]
combination for invocation context
org.jboss.ejb.client.EJBClientInvocationContext#184f6be2 at
org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:798)
at
org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:128)
at
org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:186)
at
org.jboss.ejb.client.EJBInvocationHandler.sendRequestWithPossibleRetries(EJBInvocationHandler.java:255)
at
org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:200)
at
org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:183)
at
org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:146)
at com.sun.proxy.$Proxy0.tstPlus(Unknown Source) at
test.ClientTest.main(ClientTest.java:20) at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498) at
com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Please, how can I fix this error? Am I doing something wrong? Is configuration of my artifact which I deploy on the server right?
Related
I tried to testing my Dao class but it return this error for the class DbConnection:
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or in an application resource file: java.naming.factory.initial
at java.naming/javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:691)
at java.naming/javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:305)
at java.naming/javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:342)
at java.naming/javax.naming.InitialContext.lookup(InitialContext.java:409)
at model.DbConnection.(DbConnection.java:16)
at model.DbConnection.getInstance(DbConnection.java:30)
at model.ProfileManager.ReturnPatientByKey(ProfileManager.java:27)
at model.ProfileManagerTest.testReturnPatientByKey(ProfileManagerTest.java:32)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
....
my DbConnection class:
package model;
import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class DbConnection {
private DbConnection() {
Context ctx;
try {
ctx = new InitialContext();
ds = (DataSource)ctx.lookup("java:comp/env/jdbc/CheckUpDb");
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Connection getConnection() throws SQLException {
return ds.getConnection();
}
public static DbConnection getInstance () {
if(db==null) {
return new DbConnection();
}
else {
return db;
}
}
private static DataSource ds;
private static DbConnection db;
}
Database connection works in the web application, only the testing return this error.
I don't think the problem si my class ProfileManager because it is only a testing example:
import static org.junit.Assert.assertTrue;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.*;
import model.Bean.PatientBean;
class ProfileManagerTest{
private ProfileManager pm;
String fiscal_code;
String user_password;
PatientBean patient;
#BeforeEach
void setUp() throws Exception {
this.pm = new ProfileManager();
fiscal_code = "aaa";
user_password = "bbb";
patient = mock(PatientBean.class);
}
#AfterEach
void tearDown() throws Exception {
}
#Test
void testReturnPatientByKey() {
patient = (PatientBean) pm.ReturnPatientByKey(fiscal_code, user_password);
assertTrue(true);
}
}
Database connection works in the web application, only the testing return this error.
That's most likely because you have the datasource declared in the server configuration and the server is providing your web app with one, but you don't have the same done in your test.
Do a search in your server files an you will probably discover something like this, or similar, depending on what server you use:
<Resource name="jdbc/CheckUpDb"
driverClassName="..."
type="..."
url="..."
username="..."
password="..."
/>
This is a way to configure a datasource using JNDI. When your web application runs, the server will provide you with this resource by name. This is what ctx.lookup("java:comp/env/jdbc/CheckUpDb"); does. It asks the server to give it that resource.
But when you run your unit tests, you run outside the server environment. That means that any resource you defined in the server (using context.xml for example) doesn't exist when you run your tests. In your tests you have to provide a datasource and make it available to your JNDI context so that this line of code then works:
ds = (DataSource)ctx.lookup("java:comp/env/jdbc/CheckUpDb");
The following post should give you the necessary details to set up your JNDI data source for your test: Setting up JNDI Datasource in jUnit
You will see that the examples there make use of a library called Simple-Jndi that they use to provide a JNDI context and configure it to include the datasource that the tests then try to retrieve by name. You can use any JNDI provider, but you must set up the datasource for your test yourself (inside #BeforeEach or #BeforeAll) because when running unit tests, you don't have the tomcat server doing this for you.
I am learning about EJB and I would like to get the following code working but so far no success.
Here's my EJB project code:
#Stateless
public class CalcBean implements ICalcRemote {
private static final long serialVersionUID = 5571798968598315142L;
#Override
public int add(int a, int b) {
return a + b;
}
}
package com.ejb.test.pckg;
import javax.ejb.Remote;
#Remote
public interface ICalcRemote extends ICalculator {
}
package com.ejb.test.pckg;
import java.io.Serializable;
public interface ICalculator extends Serializable {
public int add(int a, int b);
}
I run glassfish-4.1.1 in Eclipse Neon.
When I deploy the EJB project, I can see the following in the log:
2017-02-24T21:18:09.036-0400|Info: Portable JNDI names for EJB CalcBean: [java:global/EJBDemo/CalcBean, java:global/EJBDemo/CalcBean!com.ejb.test.pckg.ICalcRemote]
2017-02-24T21:18:09.036-0400|Info: Glassfish-specific (Non-portable) JNDI names for EJB CalcBean: [com.ejb.test.pckg.ICalcRemote#com.ejb.test.pckg.ICalcRemote, com.ejb.test.pckg.ICalcRemote]
This is my client code:
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import com.ejb.test.pckg.ICalcRemote;
public class Main {
public static void main(String[] args) {
try {
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");
Context ctx = new InitialContext();
ICalcRemote calc = (ICalcRemote) ctx.lookup("java:global/EJBDemo/CalcBean!com.ejb.test.pckg.ICalcRemote");
System.out.println(calc.add(5, 7));
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* (non-Java-doc)
*
* #see java.lang.Object#Object()
*/
public Main() {
super();
}
}
But I am having no luck. Any suggestions how to get this working?
Thank you!
EDIT:
This is my main (client) which includes info from the EJBDemo deployment log:
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import com.ejb.test.pckg.ICalcRemote;
public class Main {
public static void main(String[] args) {
try {
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");
/*
* THIS IS from Glassfish log of EJBDemo deployment
*
* 2017-02-25T20:41:47.100-0400|Info: Portable JNDI names for EJB CalcBean: [java:global/EJBDemo/CalcBean,
* java:global/EJBDemo/CalcBean!com.ejb.test.pckg.ICalcRemote] 2017-02-25T20:41:47.100-0400|Info: Glassfish-specific (Non-portable) JNDI names for EJB CalcBean:
* [com.ejb.test.pckg.ICalcRemote#com.ejb.test.pckg.ICalcRemote, com.ejb.test.pckg.ICalcRemote]
*
*
*/
Context ctx = new InitialContext();
ICalcRemote calc = (ICalcRemote) ctx.lookup("java:global/EJBDemo/CalcBean!com.ejb.test.pckg.ICalcRemote");
System.out.println(calc.add(5, 7));
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* (non-Java-doc)
*
* #see java.lang.Object#Object()
*/
public Main() {
super();
}
}
I finally got things working! Since it's been quite a process despite reading many posts related to this issue. Here are the details of my configuration. Hopefully, this will be useful to somebody.
OS: win 10
IDE: Eclipse Neon
App server: Glassfish 4.1.1
JDK: 1.8.0_111
I need to mention this article which eventually led me to the answer:
http://mavicode.com/2014/08/a-standalone-client-for-ejbs-running-on-glassfish-4/
So, thanks and kudos.
First, create the EJB Demo project:
package com.ejb.test.pckg;
import java.io.Serializable;
public interface ICalculator extends Serializable {
public int add(int a, int b);
}
package com.ejb.test.pckg;
import javax.ejb.Remote;
#Remote
public interface ICalcRemote extends ICalculator {
}
package com.ejb.test.pckg;
import javax.ejb.Stateless;
// #Stateless(mappedName = "chester")
#Stateless
public class CalcBean implements ICalcRemote {
private static final long serialVersionUID = 5571798968598315142L;
#Override
public int add(int a, int b) {
return a + b;
}
}
Deploy it on the server (run as > run on the server) > check the log to see the JDNI info. It should look like something like this:
2017-02-25T20:41:47.100-0400|Info: Portable JNDI names for EJB
CalcBean: [java:global/EJBDemo/CalcBean,
java:global/EJBDemo/CalcBean!com.ejb.test.pckg.ICalcRemote]
2017-02-25T20:41:47.100-0400|Info: Glassfish-specific (Non-portable)
JNDI names for EJB CalcBean:
[com.ejb.test.pckg.ICalcRemote#com.ejb.test.pckg.ICalcRemote,
com.ejb.test.pckg.ICalcRemote]
After that, create Application Client Project. Main.java will be created automatically. This is my main:
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import com.ejb.test.pckg.ICalcRemote;
public class Main {
public static void main(String[] args) {
try {
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");
Context ctx = new InitialContext();
ICalcRemote calc = (ICalcRemote) ctx.lookup("java:global/EJBDemo/CalcBean!com.ejb.test.pckg.ICalcRemote");
System.out.println(calc.add(5, 43));
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* (non-Java-doc)
*
* #see java.lang.Object#Object()
*/
public Main() {
super();
}
}
At this point, my project looks like this:
And here comes the key part. Add a new external library from the Glassfish lib directory. !!! IMPORTANT: Don't just copy and paste to the path! The .jar apparently uses/references other classes in other GF jars. So just add it to the build path as an external jar instead of copy/paste.
You should be set now. Run the Main as a Java application.
This is what I get.
I am trying to deploy a webservice on my localhost, but it doesn't seem to produce the "Endpoint".
I don't know how I messed it up :(
I am using apache cxf 2.7.1 and glassfish 3.1. I even attempted to add ear libraries.
Here is my build path:
and my project explorer looks like this:
I have annotations on both my webservice and webservice interface, as shown below:
Code for webservice interface (I removed the other some parts to make the code shorter)
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import no.solarsoft.venus2.webservice.exception.WebServiceException;
import no.solarsoft.venus2.webservice.queryoptions.ParticipantQuery;
import no.solarsoft.venus2.webservice.queryoptions.ParticipantQueryParameterKey;
import no.solarsoft.venus2.webservice.queryoptions.QueryParameter;
#WebService()
public interface WebServiceVenus2Interface {
/**
* FETCHING DATA FROM DATABASE
*
*/
#WebMethod
public void Foo(ParticipantQueryParameterKey pqpk);
#WebMethod
public String test();
#WebMethod
public String sayHello(String string) throws WebServiceException;
The code for my web service:
import javax.annotation.Resource;
import javax.jws.WebParam;
import javax.servlet.http.HttpServletRequest;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import no.solarsoft.venus2.datamanager.CRUDOperation;
import no.solarsoft.venus2.datamanager.DataManager;
import no.solarsoft.venus2.entities.GradeScale;
import no.solarsoft.venus2.enums.ImageType;
import no.solarsoft.venus2.exception.DataAccessException;
import no.solarsoft.venus2.exception.InstanceNotFoundException;
import no.solarsoft.venus2.service.EmailService;
import no.solarsoft.venus2.webservice.exception.ParameterValidationException;
import no.solarsoft.venus2.webservice.exception.WebServiceException;
import no.solarsoft.venus2.webservice.exception.WebServiceFaultBean;
import no.solarsoft.venus2.webservice.queryoptions.ParticipantQuery;
import no.solarsoft.venus2.webservice.queryoptions.ParticipantQueryParameterKey;
import no.solarsoft.venus2.webservice.queryoptions.QueryParameter;
// #Stateless()
#javax.jws.WebService(endpointInterface = "no.solarsoft.venus2.webservice.WebServiceVenus2Interface", serviceName = "WebServiceVenus2Service")
public class WebServiceVenus2 implements WebServiceVenus2Interface {
private DataManager dataManager = DataManager.getInstance();
private static final Logger log = Logger.getAnonymousLogger();
#Resource
WebServiceContext wsContext;
#Override
public void Foo(ParticipantQueryParameterKey pqpk) {}
private void logEntered(String login) {
log.info(MessageFormat.format("{0}: ''{1}'' entered web service method ''{2}()''",
WebServiceVenus2.class.getSimpleName(), login, getMethodName()));
}
private String getClientIp() {
MessageContext mc = wsContext.getMessageContext();
HttpServletRequest req = (HttpServletRequest) mc.get(MessageContext.SERVLET_REQUEST);
return req.getRemoteAddr();
}
/**
* Get the method name for a depth in call stack. <br />
* Utility function
*
* #param depth
* depth in the call stack (0 means current method, 1 means call method, ...)
* #return method name
*/
public static String getMethodName() {
final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
return ste[3].getMethodName(); // Thank you Tom Tresansky
}
/**
* FETCHING DATA FROM DATABASE
*/
#Override
public String test() {
String ip = getClientIp();
logEntered(ip);
return "WebService test succeded! Client IP: " + ip;
}
#Override
public String sayHello(String string) throws WebServiceException {
logEntered(null);
if (string == null || string.isEmpty()) {
log.severe("Throwing excetion...");
throw new WebServiceException("String can not be empty or NULL!", new WebServiceFaultBean());
}
log.exiting(WebServiceVenus2.class.getName(), WebServiceVenus2.getMethodName());
return "Hello " + string + "!";
}
and here is my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
</web-app>
I hope someone can help me. Thanks
I loaded this code nearly verbatim to a dynamic web module in eclipse and deployed to Glassfish4. When deployed (using eclipse "add to server") the WSDL is available at http://localhost:8181/Venus2WebService/WebServiceVenus2Service?wsdl
and the web service endpoint is http://localhost:8181/Venus2WebService/WebServiceVenus2Service
The only jars I included from CXF (not shown in your post) are, from reading WHICH_JARS readme within CXF binary distribution lib dir:
asm-3.3.1.jar
commons-logging-1.1.1.jar
cxf-2.7.17.jar
geronimo-javamail_1.4_spec-1.7.1.jar
geronimo-jaxws_2.2_spec-1.1.jar
jaxb-api-2.2.6.jar
jaxb-impl-2.2.6.jar
neethi-3.0.3.jar
stax2-api-3.1.4.jar
wsdl4j-1.6.3.jar
xmlschema-core-2.1.0.jar
I got the endpoint URL from watching the eclipse console for the server:
2015-09-09T21:45:40.683-0400|Info: Webservice Endpoint deployed WebServiceVenus2
listening at address at http://oc-mbp01.local:8181/Venus2WebService/WebServiceVenus2Service.
Classpath (all in WEB-INF/lib for me):
This issue is very common. I have read some articles but can't find the problem. I want to create a simple HelloWorld program in EJB 3.0, eclipse luna, jboss 7.1.1 Final.
Here is my bean:
package com.tcs.HelloWorldPack;
import javax.ejb.Stateless;
/**
* Session Bean implementation class HelloWorld
*/
#Stateless(mappedName="HelloWorldBean")
public class HelloWorld implements HelloWorldRemote {
/**
* Default constructor.
*/
public HelloWorld() {
// TODO Auto-generated constructor stub
}
#Override
public void displayMsg() {
// TODO Auto-generated method stub
System.out.println("Hello World!!");
}
}
Here is my remote interface:
package com.tcs.HelloWorldPack;
import javax.ejb.Local;
//import javax.ejb.Remote;
import javax.ejb.Remote;
#Remote
public interface HelloWorldRemote {
void displayMsg();
}
Here is my client which is running in the same machine:
package com.tcs.HelloWorldClient;
import java.util.Hashtable;
import java.util.Properties;
import com.tcs.HelloWorldPack.*;
import javax.ejb.EJB;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class HelloWorldClient {
public static void main(String[] args) throws NamingException {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
jndiProperties.put(javax.naming.Context.SECURITY_PRINCIPAL, "myUser");
jndiProperties.put(javax.naming.Context.SECURITY_CREDENTIALS, "myPass");
// jndiProperties.put(javax.naming.Context.PROVIDER_URL, "jnp://localhost:1099");
// jndiProperties.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProperties.put("jboss.naming.client.ejb.context", true);
final Context context = new InitialContext(jndiProperties);
final String appName= "HeloWorldEJBEAR";
final String moduleName= "";
final String distinctName ="";
final String beanName = "HeloWorld";
final String viewClassName = "com.tcs.HelloWorldPack.HelloWorldRemote";
HelloWorldRemote hello = (HelloWorldRemote) context.lookup("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + viewClassName);
hello.displayMsg();
}
}
This is my jboss-ejb-client.properties file:
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port = 4447
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
remote.connection.default.username=myUser
remote.connection.default.password=myPass
I have put the properties file in the classpath also.But this is happening when I am trying to run it:
Exception in thread "main" java.lang.IllegalStateException: No EJB receiver available for handling [appName:HeloWorldEJBEAR,modulename:,distinctname:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext#413ded77
at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:584)
at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:119)
at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:181)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:136)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:121)
at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:104)
at com.sun.proxy.$Proxy0.displayMsg(Unknown Source)
at com.tcs.HelloWorldClient.HelloWorldClient.main(HelloWorldClient.java:71)
Jan 08, 2015 3:34:44 PM org.jboss.ejb.client.remoting.ChannelAssociation$ResponseReceiver handleEnd
INFO: Channel Channel ID de8d2aa6 (outbound) of Remoting connection 44477156 to localhost/127.0.0.1:4447 can no longer process messages
I have also uploaded my directory structure. I am new to the EJB concept. Please help me to find where is the problem. Thanks in advance.
Your module name is an empty String, but the module name can't be an empty string in the JNDI name.
Look here
you have to set the name of your ejb module .jar, without the .jar suffix.
final String moduleName = "HeloWorldEJB";
Then it should work.
As you are out to do a simple example lets keeep it simple [KISS],Most of your code is correct the catch is the client, I have simplified the client code, added my comments in client hope its self explanatory.And.... Added on EJB #javax.ejb.Stateless(name = "HelloWorldEJB") //This is portable No Vendor locked in. Alternative is mappedName [removed from your code #Stateless(mappedName="HelloWorldBean") p]which i believe is more weblogic and glassfish centric.
Ensure you have client.jar in your class path. this is the only jar you will have to add aftr you have created the EJB project in intelija or eclipse or any other ide.
I have deployed the EJB's in glassfish container once ear deployed successfully, run the client.
Apart from the below code you wont need any other configurations. This code is portable and should work on most containers however Surprises is fun do run as is and let me know .....
Once the below works for you you can add other jndi properties as per your project requirement and move on.....
==============================
The Remote
package com.au.ejbs;
import javax.ejb.Remote;
#Remote
public interface HelloWorldI {
String displayMessage(String message);
}
=================================
2. The Impl
package com.au.ejbs;
import javax.ejb.Remote;
#javax.ejb.Stateless(name = "HelloWorldEJB")
public class HelloWorld implements HelloWorldI {
#Override
public String displayMessage(String message) {
// TODO Auto-generated method stub
return "Returning from Remote" + message;
}
}
======================================
3. The client
package com.au.clients;
import com.au.ejbs.HelloWorldI;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class HelloWorldT {
public static void main(String[] args) throws NamingException {
Context context = new InitialContext();
HelloWorldI helloWorldI = (HelloWorldI)context.lookup("java:global/ejb3_2_ear_exploded/ejb/HelloWorldEJB");
//portable syntax java:global/[ ear name]/[module name normally the jar name in my case ejb.jar within the ear, ejb3_2_ear_exploded]/name in ....javax.ejb.Stateless(name = "HelloWorldEJB")/
System.out.println( "output " + helloWorldI.displayMessage("From Client with luv...."));
}
}
===================
4. output
output Returning from RemoteFrom Client with luv....
iam getting below error when calling the ejb from jsf application
javax.naming.NamingException: ejb ref resolution error for remote business interfaceretail.ejb.service.CustomerSessionBeanRemote [Root exception is java.lang.ClassNotFoundException: retail.ejb.service.CustomerSessionBeanRemote]
here is the code below.
Interface : CustomerSessionBean
package retail.ejb.service;
import retail.model.vo.Customer;
public interface CustomerSessionBean {
public void insterCustomerDetails(Customer customer);
}
package retail.ejb.service;
import javax.ejb.Remote;
import retail.model.vo.Customer;
#Remote
public interface CustomerSessionBeanRemote extends CustomerSessionBean{
void insterCustomerDetails(Customer customer);
}
package retail.ejb.service;
import javax.ejb.Local;
import retail.model.vo.Customer;
#Local
public interface CustomerSessionBeanLocal extends CustomerSessionBean{
void insterCustomerDetails(Customer customer);
}
package retail.ejb.service;
import javax.ejb.Stateless;
import retail.model.vo.Customer;
#Stateless(name="CustomerSessionBeanImpl", mappedName="ejb/CustomerSessionBeanImplJNDI")
public class CustomerSessionBeanImpl implements CustomerSessionBeanRemote,CustomerSessionBeanLocal,CustomerSessionBean{
#Override
public void insterCustomerDetails(Customer customer) {
// TODO Auto-generated method stub
System.out.println("Customer object ::::" + customer);
}
}
package retail.web.mbean;
import java.io.Serializable;
import java.util.Properties;
import javax.faces.bean.ManagedBean;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import retail.ejb.service.CustomerSessionBeanRemote;
import retail.model.vo.Customer;
#ManagedBean
public class CustomerMB implements Serializable{
/**
*
*/
private static final long serialVersionUID = -4402277663508618618L;
private Customer customer = new Customer();
public void CustomerMB(){
System.out.println("customer method +++++++++++++++++++++++"+getCustomer());
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public String createCustomer() throws NamingException{
try{
System.out.println("in Create customer method +++++++++++++++++++++++");
Properties p = new Properties();
//properties.put("java.naming.factory.initial","com.sun.jndi.cosnaming.CNCtxFactory");
p.setProperty("java.naming.factory.initial", "com.sun.enterprise.naming.impl.SerialInitContextFactory");
p.setProperty("java.naming.factory.url.pkgs", "com.sun.enterprise.naming");
p.setProperty("java.naming.factory.state", "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
p.setProperty("org.omg.CORBA.ORBInitialHost", "localhost");
p.setProperty("org.omg.CORBA.ORBInitialPort", "3700"); //any configured port different from 3700 - 34513
InitialContext c = new InitialContext(p);
CustomerSessionBeanRemote remote = (CustomerSessionBeanRemote) c.lookup("ejb/CustomerSessionBeanImplJNDI");
remote.insterCustomerDetails(getCustomer());
}catch(Exception e){
e.printStackTrace();
}
//System.exit(1);
return "viewCustomerDetails";
}
}
Caused by: javax.naming.NamingException: ejb ref resolution error for remote business interfaceretail.ejb.service.CustomerSessionBeanRemote [Root exception is java.lang.ClassNotFoundException: retail.ejb.service.CustomerSessionBeanRemote]
at com.sun.ejb.EJBUtils.lookupRemote30BusinessObject(EJBUtils.java:433)
at com.sun.ejb.containers.RemoteBusinessObjectFactory.getObjectInstance(RemoteBusinessObjectFactory.java:75)
at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
at com.sun.enterprise.naming.impl.SerialContext.getObjectInstance(SerialContext.java:556)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:514)
... 43 more
Caused by: java.lang.ClassNotFoundException: retail.ejb.service.CustomerSessionBeanRemote
at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1509)
at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1359)
at com.sun.ejb.EJBUtils.getBusinessIntfClassLoader(EJBUtils.java:687)
at com.sun.ejb.EJBUtils.loadGeneratedRemoteBusinessClasses(EJBUtils.java:462)
at com.sun.ejb.EJBUtils.lookupRemote30BusinessObject(EJBUtils.java:413)
... 47 more
Please suggest anyone
A possible reason may be
EJB 3.0 specification warns Applications that use mappedNames may not be portable
Is this working without mappedNames or by looking up full qualified bean name?
You can see the portable name of a bean in Glassfish log, use that name instead.