I have a weird (?) problem with an EJB I want to deploy to my Glassfish 3.1 application server.
I have this bean, which should be executed continuously in Glassfish using the #Schedule annotation. This worked fine for me until I added some code to the EJB accessing a database.
#Stateless
public class MyBean implements MyBeanLocal {
#Schedule(second = "*", minute = "*", hour = "*")
public void initiateProcess() {
MyCoordinator mc = new MyCoordinatorImpl();
List<Entity> entities = mc.methodAccessingDB();
}
}
This is my EJB, which is executed every second. How I said above, I can deploy this EJB and it executed successfully, if I don't call ac.methodAccessingDB().
This means, that I can't even deploy it to Glassfish. Glassfish tells me
Invalid ejb jar [...]: it contains zero ejb. Note: 1. A valid ejb jar
requires at least one session, entity (1.x/2.x style), or
message-driven bean. 2. EJB3+ entity beans (#Entity) are POJOs and
please package them as library jar. 3. If the jar file contains valid
EJBs which are annotated with EJB component level annotations
(#Stateless, #Stateful, #MessageDriven, #Singleton), please check
server.log to see whether the annotations were processed properly..
Please see server.log for more details.
If I just write List<Entity> entities = null; instead of List<Entity> entities = ac.methodAccessingDB(); I can deploy it and it runs fine.
OK, now I have found the solution for this problem. The EJB couldn't find the classes on the deployed version. The solution was to pack everything into an ear project. I am using maven, so I created in the end 3 projects.
one for the EJB <packaging>ejb</packaging>
one for the EAR <packaging>ear</packaging>
and a third parent project, which integrates the both other projects as <module>.
I then deployed the packed ear to Glassfish and the timer started and everything was there.
Related
I currently have the following project structure
EAR
|---myapp1.war
|---myapp2.war
|---myapp-ejb.jar
I would like to get rid of the ear and deploy myapp1 and myapp2 on their own. I tried to make myapp-ejb.jar a maven dependency of the two war and everything works fine at compile time. Nevertheless, there are a lot of jndi lookups in the code that fail at deploy time. Is there a way to make this to work?
Theoretically, it is possible to have ejb in a web archive (war).
Although not necessary, you could try to put a 'ejb-jar.xml' file (located in the WAR module’s WEB-INF) to replace the normal auto-discovery mechanism ?
Be also aware that the WAR file must be version 2.5 or later to contain EJB content.
Extract the WAR from the EAR
Scope ejbs as "provided" per https://stackoverflow.com/a/42847318/8528208
Place the ejb.jar in your WAR's WEB-INF/lib per https://stackoverflow.com/a/6968674/8528208
Further documentation at https://www.ibm.com/docs/en/was/8.5.5?topic=modules-ejb-content-in-war
--
Archived edits comments refer to:
Update-
Is the ejb.jar in the build class path of your .war? If your project is maven based, is the ejb.jar a dependency of the .war project? If so, try adding the EJB module as a "provided" dependency per https://stackoverflow.com/a/42847318/8528208
--
"An .ear file is a collection of entities (i.e., .war files), so you can simply extract the .war file from the .ear file and deploy it."
-per https://stackoverflow.com/a/26658071
If this doesn't help, can you add a lookup attribute in your #EJB annotations such as
#EJB(lookup="java:global/mwf_ejb/UserManager")
Similar to this answer?
https://stackoverflow.com/a/10156279/8528208
I'm writing an answer to my own question, since I solved the issue. It is perfectly fine to use EJBs with a WAR only (no EAR) as stated here https://docs.oracle.com/cd/E19798-01/821-1841/gippi/index.html.
As for the lookups calls, the correct way to do it is described here https://docs.oracle.com/cd/E19798-01/821-1841/girgn/index.html.
The issue I was facing wasn't really related to the lookups, as I was thinking, but it was due to the way most of the EJBs were initialized.
I noticed that in most of the classes there was some nasty initialization code like the following:
#Stateless
public class FooResource
{
FooEjb fooEjb = lookupFooEjb();
private FooEjb lookupFooEjb()
{
javax.naming.Context c = new InitialContext();
return (FooEjb) c.lookup("java:global/FooApplication/FooModule/FooEJB!FooInterface");
}
}
This works fine with the EAR because the EJB module is loaded before the WAR archives, so the lookups do not fail.
My guess is that when you package the EJBs with the WAR, it loads the EJBs as they are needed, computing the dependencies based on the #EJB annotation, so that kind of initialization fails since the EJB might be not loaded yet. To make it work, I just removed the lookup and added the annotation #EJB.
#Stateless
public class FooResource
{
#EJB
FooEjb fooEjb;
}
I use GlassFish 4 web profile and I have the following interface and class.
#Local
public interface SomeService {
...
}
#Singleton
public class SomeServiceBean implements SomeService {
...
}
When I put interface and class in .war archive (that is in domain1/autodeplay) everything works fine. However, when I put interface and class in separate .jar archive (that is in domain1/lib) then deploying war application I get:
java.lang.RuntimeException: Cannot resolve reference Local ejb-ref name=com.temp.MyServlet/someService,Local 3.x interface =com.temp.SomeService,ejb-link=null,lookup=,mappedName=,jndi-name=,refType=Session
at com.sun.enterprise.deployment.util.ComponentValidator.accept(ComponentValidator.java:374) ~[dol.jar:na]
at com.sun.enterprise.deployment.util.DefaultDOLVisitor.accept(DefaultDOLVisitor.java:78) ~[dol.jar:na]
at com.sun.enterprise.deployment.util.ComponentValidator.accept(ComponentValidator.java:123) ~[dol.jar:na]
at com.sun.enterprise.deployment.util.ApplicationValidator.accept(ApplicationValidator.java:152) ~[dol.jar:n
...
I don't use any xml descriptors. So, is it possible to have EJBs in domain1/lib and if yes, how to make EJB container find them? P.S. I tried in GF 4 full - result is the same.
EJBs cannot be added as a library to GlassFish, libraries are just added to the classpath and any annotations on them are ignored and they do not go through the EJB container. If you do want your EJBs as a seperate JAR, they can be deployed just like a WAR or EAR file.
In the Glassfish reference manual for the add-library command it says that it "adds the library to the class loader directory", while for the deploy command it says that "Applications can be...EJB modules".
Also by looking at the source code for Glassfish it can be worked out that all libraries are simply added to the Classloader either at launch (See here and here) or if in applibs then when the application is deployed (See here).
I have the following code that I'm trying to deploy as an EJB to WebLogic 12c, but I'm getting an error:
"Error deploying the EJB GeopoliticalServiceBean(Application:
campaigner-ejb, EJBComponent: campaigner-service.jar), the JNDI name
java:global/campaigner-ejb/campaigner-service/GeopoliticalServiceBean!com.dr_dee_sw.campaigner.service.GeopoliticalServiceLocal
is already in use. You must set a different JNDI name in the
weblogic-ejb-jar.xml deployment descriptor or corresponding annotation
for this EJB before it can be deployed."
public interface GeopoliticalService
{
...
}
#Local
public interface GeopoliticalServiceLocal extends GeopoliticalService
{
}
#Remote
public interface GeopoliticalServiceRemote extends GeopoliticalService
{
}
#TransactionManagement(value = TransactionManagementType.CONTAINER)
#TransactionAttribute(value = TransactionAttributeType.REQUIRED)
#Stateless
public class GeopoliticalServiceBean implements GeopoliticalServiceLocal,GeopoliticalServiceRemote
{
...
}
More information:
I've reduced the EJB-JAR file, campaigner-service.jar, so that there's only one bean in it, plus the interfaces and exceptions. the EAR file, campaigner-ejb.ear, has only the EJB-JAR in it at the main level. It also has a "lib" directory with supporting libraries, but it only has the DAO and DTO jars in it plus third-party libraries. So, to me, it doesn't seem like a packaging issue.
This is my first app using all annotations, but it still seems fairly straight-forward. What am I missing?
During the migration from Weblogic 10 to Weblogic 12 we faced the same issue.
We could reproduce the issue by deploying the EAR on a fresh server without the datasources configured properly; this would cause a NameNotFoundException during deployment. Every next attempt to deploy the EAR would result in the JDNI name is already in use, even after restarting, undeploying, redeploying.
The only thing that resolved the issue was removing the cache (and most importantly the EJBCompilerCache) and tmp folder of the target server.
WebLogic caches artefacts even if they are undeployed (deleted). The solution is to remove the caches.
Solution
For each domain you should remove the cached artefacts. For example for svc domain, stop all the servers (Admin and managed), then
Execute the following to delete the tmp and EJB caches.
cd /data/weblogic/Oracle/products/Oracle_Home/fusion/user_projects/domains/svc
rm -fr ./servers/svc_srv1/cache/EJBCompilerCache
rm -fr ./servers/Administrator/cache/EJBCompilerCache
rm -fr ./servers/AdminServer/tmp
rm -fr ./servers/svc_srv1/tmp
Otherwise, from weblogic admin console, go to Home >Summary of Servers >YOUR_DOMAIN_NAME and then on EJBs tab tick Force Generation to true
I have an EJB X implementing interface IX; I have a web service Z deploying in WebSphere; one of its classes declares the following:
#EJB
IX ix;
When X and IX were in the same source tree as the application, this worked fine. I had it as #Singleton and #Startup, though I've sinced changed it to #Stateful.
The application has a jar it shares with another web service, and this 2nd web service can also make use of X. So I want to move X to a jar (or whatever) used by each web service.
There is a jar currently used by both web services, so I moved X, IX and another dependent class to the source tree for that jar. I compiled the jar and exported it, overwriting the jar previously used. I've opened that and verified that the three new classes are in it.
When I run the app in the server (RAD/eclipse) I get an error message:
com.ibm.ejs.container.EJBNotFoundException: EJB with interface IX not present in application Z.
As stated above, I have this declared as #EJB in a class in the application, in a place that works when IX and its supporting classes are in the same source tree.
The RAD/eclipse project for the jar file did not originally have an EJB facet, so I added that; I recompiled and etc., get the same error. I can add things to ejb-jar.xml if needed, though I thought that's what the Annotations were for. But maybe there's something the annotations don't do, or that I need to add something for, now that the bean is in a different jar.
I figure I've missed something about configuring or declaring this. Is this enough information to tell me what it is?
EJB X must be in EJB jar, not utility jar for annotations to work. Put only interface IX in utility jar, and make all other projects - EJB, WS1 and WS2 - dependent on that jar (add jar to EAR/lib for example). Pack all projects in EAR.
I have a project with a EJB implementing a JWS Webservice, like this:
#Stateless
#Remote(WebServiceTest.class)
#WebService(
serviceName="TestService",
name="TestName"
)
public class WebServiceTestImpl implements WebServiceTest {
#Override
#WebMethod(operationName="hello")
public String hello() {
return "Hello World!";
}
}
I deploy and test this perfectly on WebLogic 10.3 using a simple EAR project. Now I need to use Hibernate on my project, so from previous experiences I know that I have to use Antrl from Hibernate and not from the container, so I create a weblogic-application.xml in the EAR project:
<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-application ...>
<wls:prefer-application-packages>
<wls:package-name>antlr.*</wls:package-name>
</wls:prefer-application-packages>
</wls:weblogic-application>
Now when I deploy the EAR I get this error:
Unable to deploy EJB: WebServiceTestImpl from test-1.0.0-SNAPSHOT.jar:
***** ASSERTION FAILED *****
at weblogic.ejb.container.deployer.EJBModule.prepare(EJBModule.java:467)
at weblogic.application.internal.flow.ModuleListenerInvoker.prepare(ModuleListenerInvoker.java:199)
at weblogic.application.internal.flow.DeploymentCallbackFlow$1.next(DeploymentCallbackFlow.java:507)
at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:41)
at weblogic.application.internal.flow.DeploymentCallbackFlow.prepare(DeploymentCallbackFlow.java:149)
Truncated. see log file for complete stacktrace
Caused By: java.lang.ClassNotFoundException: test.WebServiceTestImpl_zd33dy_WSOImpl
at weblogic.utils.classloaders.GenericClassLoader.findLocalClass(GenericClassLoader.java:280)
at weblogic.utils.classloaders.GenericClassLoader.findClass(GenericClassLoader.java:253)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at weblogic.utils.classloaders.GenericClassLoader.loadClass(GenericClassLoader.java:177)
Truncated. see log file for complete stacktrace
How can I solve this? If I don't put Antlr in wls:prefer-application-packages Hibernate will not work, and if I put it I cannot deploy the webservice...
Weblogic somehow keeps precompiled versions of EJBs even though you do a new/update deployment.
this works for me with wls 10.3.5:
within the server directory of your domain (e.g. in my case /home/myUser/apps/bea/domains/myDomain/servers/AdminServer) there is a subfolder "cache/EJBCompilerCache". Stop your weblogic instance and remove the contents of this subfolder. Restart weblogic and everything will work :-)
I'm not sure if this is the same bug, but there is a known bug in Weblogic 10.3.0-2 that causes a problem when using JaxWS with an EJB v 2.x. But I'm getting a near identical error when I put the #WebService annotation on an EJB v 3.0 on Weblogic 10.3.1. The error is loading what looks like the supposedly generated local stubs that Weblogic creates, and its happening on Weblogic 10.3.0, 10.3.1, 10.3.2, and 10.3.3. (yes, I really have them all deployed ;)
I had this problem deploying session bean and then trying to convert it to web service. WebLogic seems to cache session beans somehow.
There are several solution to this:
- Rename slsb.
- Comment #Stateless and #Remote annotations, deploy application, uncomment annotations, redeploy again.
- Bounce WebLogic.