I'm using JEE version 5.0.2. I'm calling a WebMethod in a #WebService annotated class. This annotated class calls a Stateless #EJB that contains the business logic (the implementation) of the WebMethod I'm calling.
My WebService class is defined as follows:
#WebService
HandlerChain(file = "MyXService_handle.xml")
public class MyXService {
#EJB(mappedName="MyXBean", beanName="MyXBean")
public MyXBean myXBean;
#WebMethod
public String sayHello(#WebParam(name="nTimes") int nTimes) {
return myXBean.sayHello(nTimes);
}
}
My EJB is defined as follows:
#Stateless(name="MyXBean", mappedName="MyXBean")
#TransactionManagement(TransactionManagementType.BEAN)
public class MyXBean {
#PersistenceContext name="persistence/my_PU", unitName="my_PU")
protected EntityManager entityManager;
public String sayHello(int nTimes) {
String s = "";
for (int i = 0; i < nTimes; i++) {
s += "Hello";
}
return s;
}
}
I'm getting the following error:
Caused by: com.sun.enterprise.InjectionException: Exception attempting to inject Unresolved Ejb-Ref com.my.domain.MyXService/myXBean#jndi: MyXBean#null#com.my.domain.MyXBean#Session#MyXBean into class com.sun.enterprise.webservice.JAXWSServlet
at com.sun.enterprise.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:387)
at com.sun.enterprise.util.InjectionManagerImpl.inject(InjectionManagerImpl.java:206)
at com.sun.enterprise.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:117)
at com.sun.web.server.J2EEInstanceListener.handleBeforeEvent(J2EEInstanceListener.java:259)
... 31 more
Caused by: javax.naming.NameNotFoundException: MyXBean#com.my.domain.MyXBean not found
at com.sun.enterprise.naming.TransientContext.doLookup(TransientContext.java:216)
at com.sun.enterprise.naming.TransientContext.lookup(TransientContext.java:188)
at com.sun.enterprise.naming.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:74)
at com.sun.enterprise.naming.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:111)
at com.sun.enterprise.naming.SerialContext.lookup(SerialContext.java:409)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at com.sun.enterprise.naming.NamingManagerImpl.lookup(NamingManagerImpl.java:944)
at com.sun.enterprise.naming.java.javaURLContext.lookup(javaURLContext.java:173)
at com.sun.enterprise.naming.SerialContext.lookup(SerialContext.java:407)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at com.sun.enterprise.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:287)
... 34 more
|#]
The WebService class and the EJB are exactly in the same module in the same WAR. This WAR is being deployed in a Glassfish Server version 2.1.1. I only get this warning in the deploy log (server.log):
[#|2018-12-10T22:51:59.045+0100|WARNING|sun-appserver2.1|javax.enterprise.system.tools.deployment|_ThreadID=78;_ThreadName=Thread-946;_RequestID=bf2b9b34-5240-4eca-8b4b-9d16baad7c5b;|Unresolved <ejb-link>: MyXBean|#]
I'm following the Java EE 5 specification to implement all of this, so I'm trying to do my architecture "by the book".
I already tried to implement an interface as explained in here https://docs.oracle.com/javaee/5/tutorial/doc/bnbmg.html but with no avail, the error persisted.
I have no xml configuration concerning the beans. I was expecting all to work via the annotations but I'm getting the javax.Naming.NameNotFoundException explained above.
Am I missing something? I'm available to give more details if needed.
Thank you.
You are using the ejb name and the mapped name. The usage of mapped name is vendor specific. Glassfish is using this as a "global JNDI name". Since you are using both, I don't know which one will take precedence over the other. With your example, empty #EJB and #Stateless anntoations should work.
Related
I have an application (EAR) which works fine on Weblogic 12.2.1.0.0.
After I upgraded to Weblogic 12.2.1.3.0 the following exception appeared:
Caused By: com.bea.core.repackaged.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'ConfigurationStoreBean' must be of type [com.abc.xxxxx.config.ConfigurationStore], but was actually of type [com.sun.proxy.$Proxy323]
This is the interface I have:
public interface ConfigurationStore{
...
}
Implementation:
#Lock(LockType.READ)
#Singleton
#Startup
#Local(ConfigurationStore.class)
public class ConfigurationStoreBean implements ConfigurationStore {
...
}
Any idea what need to be fixed in order to my code can run on Weblogic 12.2.1.3.0?
After two hard workdays I have found the solution.
All the #EJB in the project need to be replaced to #Inject.
The tricky part here was that at the beginning I only amended the #EJBs in related java classes but that was not enough.
I'm not sure if this is a generic JEE6 question or if it is a Wildfly 10/JBoss7 EAP implementation specific question.
I'm trying to specify/override the default beanName used in my EJB JNDI mapping to something more meaningful to me.
For example:
LoginManagerBean:
#Stateless
public class LoginManagerBean extends BaseManagerBean implements LoginManager {
....
}
LoginManager:
#Local
public interface LoginManager{
....
}
In this context, WF10 will automatically create a JNDI mapping for this EJB as:
ejb:myApp/myJar/LoginManagerBean!LoginManager
In the Wildfly 10 documentation for EJB naming conventions, it says
For stateless beans:
ejb:<app-name>/<module-name>/<distinct-name>/<bean-name>!<fully-qualified-classname-of-the-remote-interface>
.... ....
bean-name : This is the name of the bean for which you are doing the
lookup. The bean name is typically the unqualified classname of the
bean implementation class, but can be overriden through either
ejb-jar.xml or via annotations. The bean name part cannot be an empty
string in the JNDI name.
However, I cannot seem to find which annotation to use to specify the bean name in an annotation. If I read the docs for #EJB it states that the beanName parameter is:
The ejb-name of the Enterprise Java Bean to which this reference is mapped
So from the docs, it does not seem that the beanName is the right parameter to use.
So how can I rename my EJB beanName in the mapping to something of my choice? For instance, what annotation can I use to make the mapping read:
ejb:myApp/myJar/MyReallyCoolName!LoginManager
If you're using JBossEAP 7/WildFly 10.x then this is JavaEE 7, although the same answer applies to Java EE 6.
You only appear to be using Local interfaces, so none of the instructions that you linked apply because they are only for remote EJB clients. Therefore these statements:
In this context, WF10 will automatically create a JNDI mapping for this EJB as:
ejb:myApp/myJar/LoginManagerBean!LoginManager
are completely incorrect.
When you deploy your application all of the JNDI names are logged in the server console:
java:global/serverapp/LoginManagerBean!com.stackoverflow.p43282192.LoginManager
java:app/serverapp/LoginManagerBean!com.stackoverflow.p43282192.LoginManager
java:module/LoginManagerBean!com.stackoverflow.p43282192.LoginManager
java:global/serverapp/LoginManagerBean
java:app/serverapp/LoginManagerBean
java:module/LoginManagerBean
Most of the time you should not care about the JNDI names because in general each EJB is unique and the server will find the right implementation:
public class LoginClient {
#EJB
private LoginManager loginManager;
...
}
If you want to use JNDI lookups and you want to create more work for yourself then you can specify the bean name:
#Stateless(name="Foo")
public class LoginManagerBean implements LoginManager {
...
which yields:
java:global/serverapp/Foo!com.stackoverflow.p43282192.LoginManager
java:app/serverapp/Foo!com.stackoverflow.p43282192.LoginManager
java:module/Foo!com.stackoverflow.p43282192.LoginManager
java:global/serverapp/Foo
java:app/serverapp/Foo
java:module/Foo
and you can look these up if you must:
LoginManager loginManager = (LoginManager)(new InitialContext().lookup("java:app/serverapp/Foo"));
or using injection:
#EJB(beanName="Foo")
private LoginManager loginManager;
BTW, I'm just deploying the sample EJB jar here (serverapp.jar). Some of the names have an additional path element if you're using an EAR file.
I am migrating Ejb 2.1 to Ejb 3.1. I changed Java Version from 1.6 to 1.8, and Ejb Version from 2.1 to 3.1. Once I made the changes, I am getting problems in the ibm-ejb-jar-bnd.xml and ibm-ejb-jar-ext.xml files.
I am getting these messages:
1: Session EJB with name 'abcEJB' not found
2: Resource reference with name 'ResourceRef_xyz' not found for this EJB or interceptor
Am I missing anything?
I have migrated from EJB 2.1 to EJB 3.1 couple of years back and I recall facing the same issues and error you are facing.
Although I don't remember the exact action that fixed the issue nor other issues I faced along the way, but I will tell you what I did to fix ALL issues, including this one.
Note: It's not an easy task to migrate, but following these next steps as described will save you lots of hassle later on.
Annotate session beans and interfaces with proper annotations:
In my case I had remote interfaces for EJB 2.1 beans. Since I did not need an actual remote interface in my application, I switched them into local interfaces.
Empty ibm-ejb-jar-bnd.xml and ibm-ejb-jar-ext.xml
Change clients to lookup either using DI, JNDI name. In my case I used JNDI lookup.
Now the code should look like this:
Session Bean interface:
#Local
public interface MySessionInterface {
// TODO :: declare business methods
}
Session bean implementation:
#stateless
public interface MySessionBeanImpl implements MySessionInterface {
// TODO :: implement business methods
}
Service Locator to lookup EJBs using JNDI:
public class ServiceLocator {
public final <T> T getLocalSession(Class<T> _class) throws NamingException {
return (T) new InitialContext().lookup("ejblocal:" + _class.getName());
}
}
Client:
public class SessionClient {
public void performOperation() {
try {
MySessionInterface session = ServiceLocator.getLocalSession(MySessionInterface.class);
// TODO :: perform business logic here
} catch (NamingException e) {
// TODO :: handle exception
}
}
}
Of course service locator can have the following improvements but I removed them for brevity:
Cache the result instead of looking it up everytime from the JNDI
Catch the checked exception NamingException and throw your own runtime exception
Hope you find it useful.
In both the ibm-ejb-jar-bnd.xml and ibm-ejb-jar-ext.xml files, the <session> element must contain the name of the EJB that it applies to. That name must match the name of an EJB defined in the corresponding ejb-jar.xml file, specifically the <ejb-name> element, or the name of the EJB identified by either the #Stateless, #Stateful, or #Singleton annotation. When using annotations, the name refers to either the name attribute of the annotation, or the simple class name.
Similarly, the <resource-ref> element must contain the name of the resource references that it applies to. In ejb-jar.xml, this would be the <res-ref-name> element. If the resource reference is defined via annotations, then the name element of the #Resource annotation, or the default name if not specified.
Excuse me for my english
I have an application that uses jax-ws and spring, it work on tomcat fine, but i should deploy it on Websphere 7.
WAS7 throws the following exception:
00000027 WSModuleDescr E WSWS7027E: JAX-WS Service Descriptions could not be correctly built because of the following error:
javax.xml.ws.WebServiceException: WSWS7054E: The Web Services
Description Language (WSDL) file could not be generated for the
com.foo.MyEndpoint Web service implementation class because of the
following error: java.lang.Exception: A WSDL Definition could not be
generated for the implementation class: com.foo.MyEndpoint at
com.ibm.ws.websvcs.wsdl.WASWSDLGenerator.generateWsdl(WASWSDLGenerator.java:230)
my endpoint classes are:
#WebService(endpointInterface = "com.foo.MyService", targetNamespace = "http://www.foo.com/xsd")
public class MyEndpoint implements MyService
{
...
}
and interface is:
#WebService(portName = "MyPort", serviceName = "MyService",
targetNamespace = "http://www.foo.com/xsd")
public interface MyService
{
...
}
Any idea what can cause that problem? How to check, what exactly is wrong here? The error message is too vague...
I figure out that, i changed my classes like the following and it works.
#WebService(targetNamespace = "http://www.foo.com/xsd")
public interface MyService
{
...
}
and endpoint class:
#WebService(endpointInterface = "com.foo.MyService", targetNamespace = "http://www.foo.com/xsd")
public class MyEndpoint implements MyService
{
...
}
I just stumbled upon the same problem but with a different root cause. Hope this will save someone a headache in the future:
I used a custom annotation (#MyAnnotation) in classes that were used inside an EAR deployment. This produced the abovementioned error while deploying. After getting rid of the annotations, the error disappeared.
Being completely new to Java EE (but not to Java itself) I'm trying to build a very simple "Enterprise Application" with Hibernate as JPA provider and JSF as the actual UI framework. For this purposes I'm using the NetBeans 7 with GlassFish 3.1.
{ApplicationName}-ejb:
I've accomplished to generate entity classes from database and local sesssion beans for these entities. Beans.xml is in place.
#Stateless
public class QuestFacade extends AbstractFacade<Quest> implements QuestFacadeLocal {
// some methods here as well as EntityManager injection ...
}
{ApplicationName}-war:
I've created a simple POJO as a backing bean for the JSF page. I've annotated it with javax.inject.#Named and javax.enterprise.context.#SessionScoped. This backing bean is now accessible from the JSF page as well as being injected when the actual page is accessed. Beans.xml is in place as well.
#Named
#SessionScoped
public class QuestBean implements Serializable {
#EJB
protected QuestFacade questFacade;
// several methods delegating lookups to the questFacade ...
}
Having this deployed and page accessed, I'm, however, getting an error from GlassFish that the QuestFacade cannot be looked up by the JNDI.
The stacktrace is quite long but the initial cause could be enough:
Caused by: javax.naming.NamingException: Lookup failed for 'model.session.QuestFacade#model.session.QuestFacade' 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: model.session.QuestFacade#model.session.QuestFacade not found]
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:518)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:455)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at com.sun.ejb.EjbNamingReferenceManagerImpl.resolveEjbReference(EjbNamingReferenceManagerImpl.java:173)
... 74 more
Caused by: javax.naming.NameNotFoundException: model.session.QuestFacade#model.session.QuestFacade not found
at com.sun.enterprise.naming.impl.TransientContext.doLookup(TransientContext.java:248)
at com.sun.enterprise.naming.impl.TransientContext.lookup(TransientContext.java:215)
at com.sun.enterprise.naming.impl.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:77)
at com.sun.enterprise.naming.impl.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:119)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:505)
... 78 more
I understand that I'm persuading GlassFish to inject an EJB from a different module within the same application. Should the #Remote interface be used instead? I've also tried to explicitely specify the name for both #Stateless and #EJB annotation but without any success.
I believe that I'm doing something fundamentaly wrong, but I cannot find out what.
Any suggestion or would be greatly appreciated!
I believe that I'm doing something fundamentaly wrong, but I cannot find out what.
What you're doing wrong is that if you implement a business interface (either #Local or #Remote), then you must declare the variable where injection takes place as having the type of that interface, not of the actual bean class.
So in your case:
#Named
#SessionScoped
public class QuestBean implements Serializable {
#EJB
protected QuestFacadeLocal questFacade;
// several methods delegating lookups to the questFacade ...
}
However, a business interface is not required in EJB when you're doing local (in-jvm) communication. As you discovered, if you don't specify a business interface at all for your EJB, you can inject the bean class itself. This is because you then automatically get the so-called no-interface view.
If you want, you can optionally declare that you want BOTH the local view and the no-interface view. In that way, you can inject your bean class in places whether either the bean type itself is declared or its business interface. For this you use the #LocalBean.
#Stateless
#LocalBean
public class QuestFacade extends AbstractFacade<Quest> implements QuestFacadeLocal {
// some methods here as well as EntityManager injection ...
}
Injection can thus happen in two ways now:
#Named
#SessionScoped
public class QuestBean implements Serializable {
#EJB
protected QuestFacadeLocal questFacade; // possible because of local view
#EJB
protected QuestFacade questFacadeN; // possible because of no-interface view
// several methods delegating lookups to the questFacade ...
}
In practice I didn't found much use for having both methods available at the same time though, but maybe this adds to your understanding.
Apparently the problem was that I generated #Local session beans. Per this tutorial it is no longer necessary (?) to specify the #Local or #Remote interface. I still not completely understand the problem though.
I Hope this answer could potentialy save up some time to somebody :-)
Jarda