Spring context not loading in jboss modules - module

We are facing an issue loading a Spring context with modules. Our project structure has a main war (a.war) with all the dependencies bundled in WEB-INF/lib. We have a separate jar (b.jar) which has Camel and CXF integrations and one Spring context XML. b.jar is dependent on another jar inside a.war and a.war loads all the Spring context files. While loading we want to load the spring context file from b.jar as well.
We tried adding jboss-deployment-structure.xml with b.jar as a dependency but it ends up with expecting the classes from a.war. If we remove this then the application is starting but the Spring context inside b.jar is not loaded and getting a NoSuchBeanDefinitionException.

Related

Get SLF4J running without coping anything into WebLogic lib-directory

I need to make SLF4J working inside the WebLogic application. According to Buttso [1] and Oracle [2], one need to copy files into domain/lib directory:
slf4j-api
slf4j-jdk14-1.6.0.jar
Then define the following handler in logging.property file:
handlers = weblogic.logging.ServerLoggingHandler
and start WebLogic with following parameter attached.
-Djava.util.logging.config.file=C:\tmp\logging.properties
I understand why the property file must be defined globally. But I don't understand, why JARs must be copied into domain/lib directory of the WebLogic. I tries to leave them inside my WAR file, but it doesn't work.
Is there a way to retain the log libraries under the control of the application? Where is this limitation come from? It is possible to utilize the JDK14 logging infrastructure of the Weblogic directly from the application as:
java.util.logging.Logger LOGGER = java.util.logging.Logger.getLogger("my.logger.Name");
LOGGER.info("JDK14 Anonymous info");
It works as expected. The handler weblogic.logging.ServerLoggingHandler is able to successfully intercept the message and forward it into WSL log file. Why SLF4J bridge is not able to do the same?
[1] Using SLF4J with WebLogic Server Logging
http://buttso.blogspot.com/2011/06/using-slf4j-with-weblogic-server.html
[2] How to Redirect SLF4J to the WebLogic Logging System?
https://support.oracle.com/epmos/faces/DocumentDisplay?id=1507456.1 (Oracle subscription needed)
SHOT DESCRIPTION:
It works perfectly with SLF4J packaged with the application. The important thing is that the API slf4j-api and the implementation slf4j-jdk14 must be loaded by the same classloader.
LONG DESCRIPTION:
By default the Weblogic classloader has a priority. If both libraries (slf4j-api and slf4j-jdk14) are located in domain/lib directory nothing can go wrong.
If slf4j-api is located in the application classpath but NOT in the Weblogic classpath, two things can happen:
SLF4J finds some wrong implementation packaged with the application. For example it could be a logback as mandatory dependency of some third party library. In this case the messages will be forwarded into the wrong implementation and they won't reach the WebLogic logging infrastructure.
SLF4J finds some implementation inside the WebLogic classpath. In this case the application will be most probably fail to be deployed because of ClassCastException.
As I said, it is possible to have all the SLF4J logging libraries inside the application. For example it is needed, if the WebLogic server is a shared instance and not under your control. Two things are needed to be done:
Ensure that only a single SLF4J implementation is packaged with the application. In our case it is slf4j-jdk14. Do maven clean to be sure, all the leftovers from previous tries are removed from WAR file!
Enforce the usage of the application classloader for loading the SLF4J library. It is done by WEB-INF/weblogic.xml like this:
<wls:weblogic-web-app xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app" 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 http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.9/weblogic-web-app.xsd">
<wls:weblogic-version>14.1.1.0</wls:weblogic-version>
<wls:context-root>test-oauth</wls:context-root>
<wls:container-descriptor>
<wls:prefer-application-packages>
<wls:package-name>org.slf4j.*</wls:package-name>
</wls:prefer-application-packages>
</wls:container-descriptor>
</wls:weblogic-web-app>
Here is a useful example how to find out, which classloader was responsible for a given class or instance.
Which classloader loaded a class of the provided instance

calling java component with multiple java classes from Mule

I am using Anypont Studio 5.3.0 and server runtime 3.7.0. I want to invoke a main() method from my component. Application is developed using Maven, SpringBoot and JPA. It sits in the jar file and have the following structure.
com
package
Application.class (with main method)
another package
Other classes
lib
other jars
META-INF
persistance.xml
MANIFEST.MF
Org
springframework boot loader and other spring classes.
when file arrives with file pattern that I detect with mule polling component I would like to invoke Java component in mule flow that has main class and all the supporting classes.
Thanks,
David
did you mavenize your Application? If yes, you can add that as a dependency in your mule project pom, which is also mavenize. But you need to make sure that the jars are added in your maven repository i.e. execute first "mvn clean install" to your java application. Otherwise, add the jars in you build path. When you are able to do those, you can create a spring bean or create a java component in mule where they could call your class with main() method.
I never came across this kind of production scenario where there is a need to call main method of java class in enterprise application. Are you sure you have only main method to access other classes, it should have initialize, spring way of injection etc. Simple answer to you question, create a mule java component and override onCall method to call Application(class).main. I will never do this kind of stuff [for sure it will give more problems based on what is being written in main method]. In general we will use main method invocation in desktop application. if possible work on (or let the application team to work on) jar file to have better initializing options

Invalid ejb jar: it contains zero ejb.

I have 2 modules: ejb and war, and ear module, that contains them. Modules build successfully, but when I try to deploy ear to glassfish, I recieve this error:
glassfish3.1.2|javax.enterprise.system.tools.admin.org.glassfish.deployment.admin|_ThreadID=17;_ThreadName=Thread-2;|Exception while deploying the app [EarModule] : Invalid ejb jar [BackEnd-1.0-SNAPSHOT.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.|#]
I really don't know what to do, I've found a lot of questions like mine, but there was no solution.
I understood, what was wrong. The problem was in run configurations, I'm using Intellij Idea and in run configurations there was build and make before run of my ear module. I removed this and after maven install it deployed successfully.
You have to add an EJB into your WAR or EAR file. Just Create a new Class and annotate it with #Stateless
I know this is very build specific and it uses Netbeans instead of the OP's IDE but because I was lead here and this will likely be useful to some users:
I had the following build:
Netbeans Enterprise Application with Maven
Glassfish 4.1
Java EE 7
I had tried migrating from a previous non-maven enterprise application and the clone didn't quite work the way I expected, there was some old ejb jars lying around that I deleted.
I had done quite a few things to fix it:
Ensure theres no ejb jars lying around that shouldn't be there. Ensure that you don't have accidently have the ejb module jar included more than once as this can result in the same error too (Manually deploying the ear and deployment through netbeans sometimes gave me different errors).
I used the #Remote interface on my EJB applications. Now you should not be importing your EJB into your War, you should use the annotations correctly as described https://docs.oracle.com/javaee/7/tutorial/ejb-intro004.htm
(This is more of a note) When you update any of your war or ejb, clean and build them before cleaning and building your ear (sounds funny right?).
If you are using interfaces for your session beans then you should put them in a separate jar, make a new project maven > java application. Do the same thing with your persistence entities. Add these as dependencies to both your ejb and war project.
This doesn't relate to me in particular but you should have at least 1 #stateless (or I think #stateful) annotation in a java class inside your ejb module for it to run (for the module to be considered an ejb).
I likely had to do a few more things that I forgot but if you still run into issues comment below and I'll try to update.
Just try to build & install your project using Maven , and then , deploy it in glassfish ( do not run your project directly from your IDE )
I encountered this problem as well. It occurred when I had imported a new EJB project into my Eclipse workspace. The project didn't have a reference to the Glassfish libraries then, since it was not yet included in the EAR deployment assembly.
Upon saving the Bean file, the IDE automatically imported javax.inject.Singleton instead of javax.ejb.Singleton. This made the code compile without warnings, but throw the same error as in the original post.

Glassfish 3.1 CDI problem with multimodule layout

I'm not sure if this is a bug in Weld or Glassfish or if I'm doing something just plain wrong.
I have three jars: api, impl and base. These jars are packaged to war that is deployed to Glassfish 3.1 (b37). The outcome is an error that states that injection point is unsatisfied in a pojo that is in impl. The failing pojo to inject is in base jar. The curious thing is that I can inject that very same failing pojo to a backing bean in my war with no fuss, and I can also just instantiate the injection dependency by hand using the old fashioned new keyword.
Any thoughts? I also have Maven based test project that replicates this if anyone is interested to see that.
Every jar has beans.xml in META-INF - even the war has beans.xml.
Ville
This problem can be solved by replacing module weld-osgi-bundle.jar (Glassfish is shipped with weld 1.1.0.Final) in Glassfish modules directory with the newest one - 1.1.1.Final. After that remove all files from domains/domain1/osgi-cache directory.

Glassfishv3 not adding jars in ear to the classpath

I have been working on this problem for one whole day but in vain without any effective solution.
I have an ear file packaged with an ejb and a handful of jar files (including hibernate and the other dependent jar files).The ejb is stateless and enabled as a web service.
The ear file has been packaged using maven and has the below structure
ear->projectrelatedejb.jar
->hibernate.jar
->otherdependent. jar
->META-INF/application.xml
->META-INF/manifest.mf
The application.xml and manifest file are automatically generated by maven when I do a package.
When I deploy this ear file on glassfish it gets deployed with the ejb methods being accessible using web services. However when accessing the application (using soapui),
the ejb methods that perform some database functionality using hibernate throw java.lang.NoClassDefFoundError for the hibernate api during runtime.
It is obvious from the error that the hibernate jars are not on the classpath during runtime but since the jars are within the ear Glassfish should have
added it to the application classpath.
I tried various options like adding the classpath entries to the manifest.mf during the package (by using the element addClasspath with the maven-ear-plugin) which didn't do any good.Also with Glassfish we cannot add the dependent jars as modules to the application.xml unless the jars are application client jars
(Glassfish wouldn't deploy the ear file if the application.xml has the dependent jars declared as modules).
I also tried placing the jars in the lib directory within the ear (which isn't actually required) and with the manifest Class-Path header referencing the jars in the lib directory which also didn't fix the problem.
The quick and dirty fix which I can do to get this working is to place the hibernate and the other the dependent jars in Glassfish's lib directory.However,this is a bad practice
and I am somewhat reluctant to do it.
I would really appreciate if someone can provide me with a working solution to this problem.I have gone through the net looking for this problem
but couldn't find any solution.
Wondering if its a bug with glassfish or does glassfish need something special to reference the jars in an ear.
Thanks in advance.
I found a similar problem which is discussed here: http://www.tricoder.net/blog/?p=59.
Simply put, try putting the libraries in EAR/lib directory and according to JEE5 spec, glassfish will add them to class path automatically.
I used Server Library option to deploy application JARs and it worked for me.
Right click on your EAR-> Properties -> Libraries-> Add Library -> Create -> give name and change type in Library Type to Server Libraries then add JARs that should be deployed and confirm.
I work with NetBeans 7.0.1 and GlassFish server 3.1
When you say you added classpath entries to manifest.mf, which manifest.mf do you refer to? The one in ear-root/META-INF/manifest.mf ? Try adding a META-INF/MANIFEST.MF to your ejb module with Class-Path entries!