I have a working Glassfish 5 setup inside of Eclipse.
I have modules set up like this:
common
- contains remote interface for singleton bean with @remote and @local annotation
- included in all other modules as a pom dependency
core
- contains a singleton bean that implements the interface in common
- intended to contain service classes stored in JNDI that allow any number of clients to lookup and store data and/or access other service logic
- builds a war file that deploys onto GlassFish
desktop
- does an InitialContext lookup of the singleton bean. (I intend to abstract this into the Service Lookup design pattern).
- intended to be a desktop client that remotely accesses beans stored on the server.
- Right now, I'm just trying to get it to remotely access the service in core and print some text to the console proving it worked.
I think my problem stems from a misunderstanding of how to store a custom bean in JNDI in the first place. I looked on Google, but I mostly find articles and answers to questions telling me to add name and mappedName to the Singleton annotation or they only show how to add a predefined bean into JDNI such as a Boolean or String, and not something custom defined.
My bean is defined like this:
@Singleton(name = "BookService", mappedName = "ejb/BookService")
public class BookServiceImpl implements BookService {
private static final long serialVersionUID = 1L;
which results in this on the Glassfish server: Core Server Screenshot
but nothing appears in JNDI: JNDI Screenshot
The client does it's InitialContext lookup like this (I've tried multiple ways of writing the JNDI name):
BookService bookService = (BookService) initialContext.lookup("java:global/core/BookService");
using these configurations (I defined my domain with a base port of 8000, so every port is 8000 + something):
glashfishEnvironmentTable = new Hashtable<String, String>();
glashfishEnvironmentTable.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.enterprise.naming.impl.SerialInitContextFactory");
glashfishEnvironmentTable.put(Context.STATE_FACTORIES,
"com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
glashfishEnvironmentTable.put(Context.URL_PKG_PREFIXES, "com.sun.enterprise.naming");
//glashfishEnvironmentTable.put(Context.PROVIDER_URL, "ejbd://localhost:8080/");
// on a different host than the appserver
glashfishEnvironmentTable.put("org.omg.CORBA.ORBInitialHost", "localhost");
// optional. Defaults to 3700. Only needed if target orb port is not 3700.
glashfishEnvironmentTable.put("org.omg.CORBA.ORBInitialPort", "8037");
I get an error like this when I run it:
Exception in thread "main" javax.naming.CommunicationException: Communication exception for SerialContext[myEnv={org.omg.CORBA.ORBInitialPort=8037, java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, org.omg.CORBA.ORBInitialHost=localhost, java.naming.factory.url.pkgs=com.sun.enterprise.naming, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl} [Root exception is java.rmi.MarshalException: CORBA MARSHAL 1330446343 No; nested exception is:
org.omg.CORBA.MARSHAL: FINE: 00810007: Underflow in BufferManagerReadStream after last fragment in message vmcid: OMG minor code: 7 completed: No]
I think my InitialContext is configured properly because when I manually define the bean in JNDI like this (The ServiceFactory doesn't do anything, because I don't know how to properly extend ObjectFactory):
I get this:
Exception in thread "main" java.lang.ClassCastException: javax.naming.Reference cannot be cast to common.service.BookService
Is there simple fix to this I am missing, or am I mixing oil and water trying to get an EJB Singleton into JNDI? Or am I missing something big like an EJBHome or a Servlet?
Do I need to extend the factory class to add my service classes into JDNI, or should ObjectFactory work? If I must extend the factory class, how would I go about it?
I hope I've defined the scope of the question well enough, but this is all new to me, so if anybody has experience implementing something like this, I appreciate any input that gets me closer to doing it right.
java:global/core/BookService
? Look into theserver.log
when deploying, it should list the JNDI names on which you can lookup the remote interface. Apart from that you do not need to do anything special to get the EJB into the JNDI. This will be done automatically when deploying. – Christoph JohnBookServiceImpl
? TheBufferUnderflow
error suggests that some of them (or your EJB) are not implementing theSerializable
interface. Also see here: stackoverflow.com/questions/7751951/… – Christoph John