slf4j Logger, LoggerFactory not working at runtime from a child jar - runtime

I am a facing an issue while using slf4j Logger and LoggerFactory in a child jar (suppose CHILD.jar).
I am deploying one EAR in WebSphere. The EAR structure is like below-
Parent ear>
META-INF
Project Specific dependency jars
Project Sub Modules bundled as jars
commons-logging-1.0.4.jar
common-logging-api-1.1.jar
CHILD.jar
In CHILD.jar's MANIFEST.MF we are not giving any CLASSPTH entry as this CHILD.jar is used by several other applications and those other applications may not use any same slf4j implementor.
Below is the MANIFEST file structure-
Manifest-Version: 1.0
Build-Jdk: 1.7.0
Built-By: C12560
Archiver-Version: Plexus Archiver
Created-By: Apache Maven 3.0.4
In our application, we are keeping all the jar at the same hierarchy where the CHILD.jar is present.
Now while deploying, no exception is thrown. At runtime, it is throwing InvocationTargetException (and NoClassDefFoundError) in all those classes where we have used org.slf4j.Logger and org.slf4j.LoggerFactory.
If we comment out all these logger entries, the application is working fine and no exception is thrown at runtime.
Even if we use org.apache.log4j.Logger instead of org.slf4j.Logger, the code is working at runtime(Note- log4j-1.2.13.jar is present in the same hierarchy as CHILD.jar).
Queries-
Is slf4j not getting its implementor?
Any jar I have to include in the hierachy same as CHILD.jar?
Please note- I have tried including jcl-over-slf4j jar and log4j-over-slf4j.jar(and removed common-logging.jar) in the same hierarchy as CHILD.jar but it didn't work.
Any help is highly appreciated.

if you want to use jcl or log4j as implementor of slf4j, what you need is slf4j-jcl.jar or slf4j-log4j.jar.
Besides, when getting a NoClassDefFoundError, you should go through the full stacktrace. Usually it is caused by some other exception.

Related

Manually overcoming ObjectMapper class not found in in a WAR archive

My build of a Business Central of JBPM is a WAR that is (intermittently?) not finding the class:
org.jboss.resteasy.spi.UnhandledException: java.lang.NoClassDefFoundError: Lorg/codehaus/jackson/map/ObjectMapper; at
org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:82) at
org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:346) at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:193) at
org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:456) at
org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:229) at
org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:135) at
...
I have placed jackson-core-2.11.3.jar and jackson-databind-2.11.3.jar in the WAR's lib directory so I think ObjectMapper should be found. But these JAR files are of bundle packaging, so contain their own pom files of dependencies. I believe the Jackson libraries are likely used elsewhere in the app where no exceptions are thrown. Is this issue related to RestEasy as a dependency? What is the appropriate way to include these dependencies into the war archive manually - since rebuilding often takes most of the day?

How is l4j ending up on my classpath after maven package?

I have a rest service running on dropwizard. Dropwizard requires slf4j to be configured with logback. When launching this service directly from my maven project in eclipse, the service starts up with the proper logback binding. When I do a maven package with the maven shade plugin, however, the resulting jar is still pulling log4j onto the classpath, which is resulting in slf4j choosing org.slf4j.impl.Log4jLoggerFactory instead of the logback binding.
I have made sure to exclude every transitive instance of log4j in my pom, as well as slf4j-log4j12 (mvn dependency:tree shows neither of these in my hierarchy), yet somehow it still always shows up in my uber jar after running mvn clean package.
How can I figure out what is causing log4j to always exist on my classpath?

spring boot System.getProperty("java.class.path") doesn't include lib/ jars

I've got a spring boot app and I'm building a myApp.jar using the spring-boot antlib. When I jar -tf myApp.jar I see that I have a jar called lib/foo.jar. Yet when I print out System.getProperty("java.class.path") I don't see that jar file on the classpath. I also get a ClassNotFound exception from URLClassLoader when the code attempts to use this class for the first time. I'm using the JarLauncher since that's what the antlib defaults to.
Any ideas why this jar file would not be on the classpath?
You won't see a bundled JAR in System.getProperty('java.class.path'). The class path specifies where the JVM will look in the filesystem for classes you attempt to load.
Spring Boot uses fat JARs, which are loaded in a completely different way. Refer to the Spring Boot documentation.

mvn jboss:deploy fails with NoClassDefFoundError

When deploying an EJB project to JBoss using JBoss Maven Plugin, I get a NoClassDefFoundError on my JBoss' console about a class that is in one of the dependencies of this EJB project.
This dependency is declared with a Compile scope. Is there another scope that I should use so that my dependencies are also deployed to JBoss? Or how should I solve this?
The error looks like this:
DEPLOYMENTS IN ERROR:
Deployment "vfszip:/Users/hordine/projects/SoftBudget/soft-budget-ejb/target/soft-budget-ejb.jar/" is in error due to the following reason(s): java.lang.NoClassDefFoundError: br/com/pedra/j2eepatterns/facade/IEntityService
I understand that you have packaged the EJB as a jar file. This means there is no any provided dependency as same as a stand-alone jar.
AFAIU, there may be 3 possible ways as the following: -
Package them as an ear and put those dependencies inside the ear/lib. Please see Maven EAR Plugin for further information.
Package them as an war and put those dependencies inside the WEB-INF/lib. Please see Maven WAR Plugin for further information.
Package them as an jar and put those dependencies inside the classpath or application server lib. Please refer to your application server document.
EDITED:
If you are using the JavaEE 6, then it is possible to package the EJB as a war file. The The Java EE 6 Tutorial: Packaging Enterprise Beans in WAR Modules told us as
Enterprise beans often provide the business logic of a web application. In these cases, packaging the enterprise bean within the web application’s WAR module simplifies deployment and application organization. Enterprise beans may be packaged within a WAR module as Java programming language class files or within a JAR file that is bundled within the WAR module.
To include enterprise bean class files in a WAR module, the class files should be in the WEB-INF/classes directory.
To include a JAR file that contains enterprise beans in a WAR module, add the JAR to the WEB-INF/lib directory of the WAR module.
WAR modules that contain enterprise beans do not require an ejb-jar.xml deployment descriptor. If the application uses ejb-jar.xml, it must be located in the WAR module’s WEB-INF directory.
I hope this may help.

Spring component-scan not scanning jboss server lib directory

I have a jar file (kept in jboss-home/server/default/lib) and a war file (kept in jboss-home/server/default/deploy). The jar file contains a servlet which initializes the spring context. The servlet is initialized from the war file.
The problem is that the #Component (and #Service, etc) annotations in the jar file are not scanned. It gives NoSuchBeanDefinitionException error. I have declared the following in context xml.
<context:component-scan base-package="com.abc.mypack" />
I have also selected "Add directory entries" when building the jar using eclipse.
If I change to xml based configuration, it works. Or, if I move the jar file to WEB-INF/lib of the war file, it works.
Is there a way to scan the jboss server lib directory for components?
I am using spring 3.1 and Jboss AS 6.
Those annotations don't scan libraries. They scan packages, which means that the libraries containing those packages need to be on the classpath.
Most-likely the libraries you're referring to are on different classloaders.
I would suggest packaging the jar within the war's WEB-INF/lib directory.

Resources