Weblogic 10.3.5 & EJB 3 JNDI names - ejb-3.0

Could someone tell me where I can find infos on the default JNDI naming for EJB 3 ?
Does Weblogic use portable JNDI names like Glassfish?
Can I find (like for Glassfish) a trace of EJB deployment with JNDI names used?
For example :
an interface (Service) with only #Remote
a bean (ServiceImpl) with only #Stateless implementing the interface
everything packaged in an .ear file (service-application-1.0)
When deploying on Weblogic the only JNDI reference I see is:
service-application-1.0service-application-1.0_jarServiceImpl_Home
but I can't use that name with a context lookup. If I do
Service myService = (Service) context.lookup("service-application-1.0service-application-1.0_jarServiceImpl_Home");
it gives me
Exception in thread "main" java.lang.ClassCastException: weblogic.ejb.container.internal.StatelessEJBHomeImpl_1035_WLStub cannot be cast to com.tuto.Service
at com.tuto.TestEjb.main(TestEjb.java:24)
PS. With Glassfish it gives me
Portable jndi names for .... : java:global/service-application-1.0/service-application-ejb-1.0/ServiceImpl
And
Service myService = (Service) context.lookup("java:global/service-application-1.0/service-application-ejb-1.0/ServiceImpl");
is working.

Unfortunately, EJB 3.0 does not specify a standard JNDI naming and leave it up to the server vendor. You are right by quoting WL documentation about mappedName: "If you specify this attribute, the stateless session bean may not be portable". The drawback of mappedName attribute is that the global JNDI name will be default to mappedName#FullyQualifiedRemoteInterface. Since mappedName is an annotation within the source code, it makes your code non-portable. The preferred way is to keep vendor-specific behavior in vendor specific deployment descriptors, such as weblogic-ejb-jar.xml. This way, you also have the choice of specifying your own custom JNDI name without the predetermined format as mappedName#FullyQualifiedRemoteInterface.
EJB 3.1 made some efforts to standardize JNDI names at global,application, and module levels. Please see http://docs.oracle.com/cd/E19798-01/821-1841/girgn/index.html

You can try context.lookup("ServiveImpl#com.Service");, where ServiveImpl is the mapped name for bean & after # it should be fully qualified interface name.

Related

JNDI resources not available for Gemini Blueprint running in Tomcat 9 (working in Bundle Activator)

I have an older Web-Application using Eclipse RAP 3.0 with Equinox OSGI-Container and Gemini Blueprint 1.0.2.
I can define my JDNI Values in server.xml
link them in context.xml and use them in my web.xml.
In my launch.ini i use the parent classloader fwk so the JNDI configuration is passed to the OSGI-Container.
My Application-Bundles can read those values for example in Bundle-Activator:
String xxx= InitialContext.doLookup("java:comp/env/xxx"); or
String xxx= new InitialContext().lookup("java:comp/env/xxx");
Some Bundle-Configuration is done via Gemini Blueprint xml files and SpringConfiguration Java classes.
<jee:jndi-lookup id="xxx" jndi-name="java:comp/env/xxx" />
This part is not working and i get following error
Error creating bean with name 'xxx': Invocation of init method failed;
nested exception is javax.naming.NameNotFoundException:
Name [java:comp/env/xxx] is not bound in this Context. Unable to find [java:comp].
I get the same Error when i use Spring-Java-Configuration which is invoked from gemini blueprint xml. Then statements like new InitialContext().lookup("java:comp/env/xxx") don't work and i get the same exception.
I think it has to to with the classloaders that are different for Bundle-Activator-Code and Gemini BlueprintExtender Thread but in can't figure it out how to solve this.
I found a Solution that i can use.
If i Move my JNDI-Lookups from xml into my Spring-Configuration-class then i can change the clasloader in init like this:
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
After that i my Lookups work fine.
i found that solution here
Can Spring Boot be used with OSGi? If not, any plans to have an OSGi Spring Boot?.

Error when trying to use both mongo and sql jpa in the same spring app

We have a spring app that works with mongodb.
Now we need it to connect also to mysql.
All the beans are defined in a applicationContext.xml legacy file.
We like that the new mysql configuration will be in java classes.
We created an entity, repository and a configuraion java files.
But it seems that as we try to do so, spring gets confused.
If we try to run the app, it start complaining about the mongo repositories:
Error creating bean with name 'MyMongoRepository': Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities
In the intellij we have the "could not autowire" error only on the sql repository (the first 3 are the mongo repositories):
Is it possible that the #configuration class is clashing with the applicationContext?
Should the #configuraion class be in a certain package/folder to work correctly?
Also, in the #configuration file, as there are green beans on the left side, it seems like intellij is able to understand where is the persistence repository.
Thanks for any help.

How can I access Spring bean from Message-driven bean in JBoss AS 7

I want to make a call to a Spring bean (a #Component) from my message-driven bean (MDB) but have problems getting a reference to it. I've tried with a class implementing org.springframework.context.ApplicationContextAware which stores the Spring ApplicationContext in a static field in a class MyAppContext. The static field in MyAppContext is then accessed from the MDB. But MyAppContext is loaded from different classloaders. The Spring application context is correctly set in the web module classloader context, but in the MDB's classloader context, it's null.
Can I somehow instruct JBoss to use the same classloader for the web app and the MDB?
Or is there a better way than storing the Spring application context in a static field?
Thanks for any advice!
A static holder for the context is not really a good idea. To make your beans available to other applications in a Java EE environment, you should consider making use of JNDI.
Unfortunately, there is no plain JNDI exporter available out of the box, but it's fairly easy to write one yourself, as shown in this blog post: http://maestro-lab.blogspot.ro/2009/01/how-to-export-spring-managed-bean-to.html
There is however a JndiRmiServiceExporter that you may want to look at.
Once your beans are bound to names in JNDI, they can be referenced using standard CDI in your message bean without worrying about class loading issues.
Why not use "ClassPathXmlApplicationContext" to load and look up for the Spring bean you require in your MBean?

JEE6 : Alternative EJB declaration

I'm using JBoss 7.1.1 with CDI.
I've got a Stateless bean named ServiceAccount in JNDI. This is the real service implementation.
I've got another Statelss bean named ServiceAccountMock which is a Mock service.
The both herited from the same interface and are packaged in a service.ear.
What I want to do is to declare the mock service as alternative in bean.xml, redeploy my services ear, and then all the client see the mock version (without changing anything on client side).
When I deploy my service.ear, JBoss says :
java.lang.IllegalArgumentException: JBAS011046: A component named 'ServiceAccount' is already defined in this module
This is true, both services are declared the same way (#Stateless(name="ServiceAccount")).
If I change the name of the mock version, I have to change on client side which EJB is used (and I don't want to do that).
Does anyone know how to do that ?
I don't think you will be able to deploy 2 beans with the same name in the same application.
If the clients of the bean are only local, you should use CDI type injection selection.
Remove the name of the beans or put different name if you realy need a name (The mock will have a different name that the real implementation).
Keep the #Alternative annotation on the mock.
At the injection point, use the interface as the type of variable (and probably using the #Inject annotation instead of the #EJB one may help).
The EJB specification and CDI aren't yet completly aligned. EJB has some element like the name that need to be unique over the application and is not taken into account in the CDI alternative functionaltity.
So I don't think you will be able to mix EJB name injection selection and CDI alternative injection selection.
First you need to annotate ServiceAccountMock with #Alternative, to tell the container not to use it if not instructed to.
#Stateless(name="ServiceAccount")
#Alternative
public class ServiceAccountMock{
....
}
Then in beans.xml you need to tell the A/S to pick the mock implementation:
...
<alternatives>
<class>xx.yy.ServiceAccountMock</class>
</alternatives>
...

Calling remote EJB3 without interface classes available

When calling remote EJB3 (Glassfish) from another EJB module, it is usual to have interfaces available, they are included as JAR file so that when you do JNDI lookup everything works as expected.
I have a situation where EJB3 JNDI name is determined at runtime, and my attempts to access the EJBs retrieved from JNDI in usual way fail, container complains ClassNotFound for remote interface classes. This is odd to me, since all the interface classes extend a parent interface for which I DO have a dependency in my calling EJB module, i.e.:
IParent ejbRef = (IParent) JndiLocator.getObject("jndinameRemote");
Is this possible with EJB3, without the need to have an exact remote EJB interface bytecode available in my JAR?
Bozo
Even though i am exactly not sure what the above setup is , I had a similar need of trying to invoke EJB when the client jars are not known during the compile time, infact in addition there is also no way for me to know what Application service is the EJB deployed at.
I had managed to do this by writing my Customized Class Loader , the catch here is that the Class which in turn tries to invoke the EJB must be itself loaded using the Customized class loader along with all the necessary jars i.e client jar with interfaces and models and the application server specific client jar.
I passed all the context properties as an input to my Invoker class to initialize context factory and invoke the bean.
These are high level steps to achieve this
Create Class EJBInvoker with method invokeEJB, you can pass it couple of Maps with properties for preparing context and Ejb interface , method , parameters classes , values and output class.
Use reflection to create instance of InitialContextFactory as well as Bean object , parameters and method invokation.
Add the above class to separate jar file and invoke the method with properties required from external project using a customized class loader.

Resources