gwt + jetty + spring + log4j ERROR: "DOMConfigurator object is not assignable to a Configurator" - spring

This problem was mentioned in several sources around the web but I was unable to solve it with solutions provided there.
PROBLEM:
The following error is thrown from log4j when issuing mvn gwt:run:
[ERROR] log4j:ERROR A "org.apache.log4j.xml.DOMConfigurator" object is not assignable to a "org.apache.log4j.spi.Configurator" variable.
[ERROR] log4j:ERROR The class "org.apache.log4j.spi.Configurator" was loaded by
[ERROR] log4j:ERROR [sun.misc.Launcher$AppClassLoader#23137792] whereas object of type
[ERROR] log4j:ERROR "org.apache.log4j.xml.DOMConfigurator" was loaded by [WebAppClassLoader=Demo#3d1665ac].
[ERROR] log4j:ERROR Could not instantiate configurator [org.apache.log4j.xml.DOMConfigurator].
DESCRIPTION of my project:
I use default jetty server provided with gwt and run it on exploded war.
<gwt.version>2.6.1</gwt.version>
<spring.version>3.2.6.RELEASE</spring.version>
<log4j.version>1.2.17</log4j.version>
<slf4j.version>1.7.5</slf4j.version>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Normally this jar would be listed in dependencies but in my case causes log4j ERROR. -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
What's more, I exclude commons-logging from spring and other projects that depend on it.
(not satisfying) SOLUTION:
Logging works fine only when log4j, slf4j-api, slf4j-log4j12 and jcl-over-slf4j jars are put in my WEB-INF/lib directory but only when jcl-over-slf4 is not in the project's classpath (i.e. I comment out the last mentioned dependency).
When jcl-overl-slf4j is included in maven dependencies (see above) it is not only added to target's lib directory but also included in project's classpath. It causes the error. This jar is necessary to be put in lib but the error disappears only when it is not included in the classpath. maven-dependency-plugin is used to work this problem around by copying it into lib directory and skipping maven dependency.
This solution is obviously just a workaround as all four jars - log4j, slf4j-api, slf4j-log4j12, jcl-over-slf4j - are mentioned in many standard examples of gwt and spring projects.
Could you explain why is it behaving that way and how could I solve this with normal inclusion of jcl-over-slf4j in maven dependencies?

Jetty treats org.apache.commons.logging as a system class, i.e. it loads it from the system class loader (i.e. the classpath) in priority over the webapp's WEB-INF/lib. In your case, org.apache.commons.logging is provided by jcl-over-slf4j. So, code in your webapp calls Commons Logging which is then loaded from the system class loader, and it probably initializes SLF4J using the class's class loader (as opposed to the current thread class loader), which thus uses code from slf4j-log4j12 and log4j from the system class loader. Later on, code in the webapp calls into Log4j (possibly through SLF4J) to initialize the logging configuration, and it then uses the JARs from the webapp's WEB-INF/lib (as expected). When it comes to put everything together, then comes the issue, with classes loaded from different class loaders.
Now to solve the issue: it's not straightforward.
Simply put, classloading in DevMode is a mess (see https://docs.google.com/document/d/1bWfafaPA0m0Z1Swodnx7m3QTv31OdqFkE7aeadN_2BU/edit?usp=sharing where I tried to document it).
To solve your issue, you'd have to either use your own ServletContainerLauncher in DevMode with your own classloading rules, or more simply run your webapp in another servlet container (e.g. mvn jetty:run or mvn tomcat7:run, or whatever). Then you'd run DevMode in -noserver mode.
It's a slightly more complex setup, but it has the big advantage of being exactly the one you'll need for SuperDevMode; and SuperDevMode will replace DevMode this year (DevMode is dead already in Firefox, and in Chrome on Linux –basically, it's dead on Linux–, and support will be removed from Chrome on other platforms later this year, leaving only one working platform: Internet Explorer on Windows).

Related

No suitable driver found for jdbc:firebirdsql://localhost:3050

I build a javafx maven app , using jaybird dependency . Every thing work fine from intelliJ.
when i export the jar file ,I receive this message :
No suitable driver found for jdbc:firebirdsql://localhost:3050...
this is dependencies part of pom.xml:
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>16</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>16</version>
</dependency>
<dependency>
<groupId>org.firebirdsql.jdbc</groupId>
<artifactId>jaybird-jdk16</artifactId>
<version>2.2.14</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.5.0</version>
</dependency>
</dependencies>
The solution is :
right click on jaybird dependency(follow the image), then click Extract into output root then rebuild the artifact jar.
The normal cause of this error occurring is that either you don't have Jaybird (Firebird JDBC driver) - or one of its required dependencies - on your classpath, or the driver was not registered. Driver registration normally happens automatically, but you can always try to do it explicitly using Class.forName("org.firebirdsql.jdbc.FBDriver"). If this fails, you get a stacktrace that provides further information.
Given you show a Maven pom.xml that includes Jaybird (albeit an older version), the driver is present at compile time. However, depending on how you launch your application, it may not be present on the runtime classpath.
There are several options:
Explicitly specify the driver when loading Java:
java -cp yourapp.jar;jaybird-4.0.3.java8.jar;connector-api-1.5.jar your.class.Name
Here, both jaybird-4.0.3.java8.jar and connector-api-1.5.jar are required for Jaybird to work.
List the required JARs (jaybird-4.0.3.java8.jar and connector-api-1.5.jar) in the Class-Path entry of the manifest of your JAR:
Class-Path: jaybird-4.0.3.java8.jar connector-api-1.5.jar
Both jar files need to be in the same directory as your JAR. You can then launch your application as (assuming the Main-Class attribute is also specified):
java -jar yourapp.jar
Create a fat (or uber) JAR, and make sure all of Jaybird's classes and resources - and those of its required dependencies - are included in your JAR.
(web applications) Include the driver (and dependencies) in the libraries/modules of your application server (e.g. the Tomcat lib folder), or make sure the driver is included in the WEB-INF/lib folder of your WAR (the Maven WAR plugin takes care of this). In this last case (driver in WEB-INF/lib), it is necessary to explicitly load the driver using Class.forName("org.firebirdsql.jdbc.FBDriver") to ensure the driver is registered.

Two Maven Dependencies with different scope

If I have the following two dependencies in the same pom.xml file:
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
And I'd like to remove the redundancy. So should I delete the one with scope as runtime because it's included in the other dependency?
Also I'd be happy to understand why one would specify a dependency with scope of runtime.
From Introduction to the Dependency Mechanism - Dependency Scope:
compile
This is the default scope, used if none is specified. Compile dependencies are available in all classpaths of a project. Furthermore, those dependencies are propagated to dependent projects.
(...)
runtime
This scope indicates that the dependency is not required for compilation, but is for execution. It is in the runtime and test classpaths, but not the compile classpath.
So if you have a compile dependency, runtime is already included and therefore superfluous.
As an example for when to use runtime, take the SLF4J logging API: you compile your sources against slf4j-api.jar (compile dependency), but not the actual implementation, which is distributed separately (and there are several to choose from). However, when packaging your application or running unit tests, Maven should still include an implementation jar, e.g. slf4j-simple.jar (runtime dependency), because otherwise nothing will be logged.

Maven: The type cannot be resolved. It is indirectly referenced from required .class files

I changed some existing projects from ant to maven projects.
So far so good.
All projects do have the same groupId.
Theres a project with name "ServerBase" and artifactId "server-base".
Within this project theres an abstract class "BaseService" which defines a logger via:
import org.jboss.logging.Logger;
[...]
protected Logger log = Logger.getLogger(this.getClass());
Theres another project with name "Server" and artifactId "server".
Within this project theres a class ConfigurationDAOImpl extending the BaseService-Class above.
Within ConfigurationDAOImpl the logger log is used for creating some outputs.
Within the "Server"'s POM file I have declared:
<dependency>
<groupId>com.tcom.amadeus</groupId>
<artifactId>server-base</artifactId>
<version>${project.version}</version>
</dependency>
Under BuildPath the dependency is shown very nice under MavenDependencies. I removed the old dirct/natural/ant-dependency from build path before.
If I remove it I am getting very much errors about missing classes etc.
But although I do have this dependency I am getting the followin error in eclipse (under tab markers):
The type org.apache.commons.logging.Log cannot be resolved. It is indirectly referenced from required .class files
Resource: ConfigurationDAPImpl.java
Path: /Server/src/main/...
Location: Line 24
Type: Java Problem
I tried removing the dependency and add it again but without any luck.
Both projects do refer to JAVA 1.8.
Both projects have been build with targets clean an package multiple times.
Both projects have been updated by Righclick or pressing F5.
I am using Eclipse Version: Neon.1a Release (4.6.1)
I am using apache-maven-3.3.9
I am using m2e Plugin.
Any further help would be grateful.
Thanks in advance.
There are two ways to 'solve' this:
1)
explicitly add the required dependency within the server-projects pom-file:
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
</dependency>
2)
change the scop of the required dependency within the server-base-projects pom file from up to now 'provide' to 'compile' or erase the scope tag at all such that the default scope is used by maven (which I guess is 'compile')
old:
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<scope>provided</scope>
</dependency>
new:
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<scope></scope>
</dependency>
or:
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
</dependency>
Some background to this from documentation:
http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Transitive_Dependencies
provided This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example,
when building a web application for the Java Enterprise Edition, you
would set the dependency on the Servlet API and related Java EE APIs
to scope provided because the web container provides those classes.
This scope is only available on the compilation and test classpath,
and is not transitive.
Thanks all.
It looks like apache logging library is not brought transitively from your server-base project. Check if in project server under MavenDependencies you see commons-logging (apache logging) jar. If not, then add this as your maven dependency in server-base project.
Repeat the above for all jars that server-base depends on.

Add log4j maven dependency to war without having it in compile time

Our application uses slf4j, but has dependency to
slf4j api
slf4j over log4j
log4j
The problem is that very often IDE imports classes from log4j and not from slf4j.
Ideally, i want to have only slf4j api as a maven dependency for my application and pack slf4j binding with log4j only at the time i building a war.
I found several solutions so far:
Add libs to WEB-INF/lib folder. This is bad, because i have no maven dependency control and have to store binary in my repo which is not the best thing to do.
Use maven-war plugin with overlays. But as i understand adding dependency to overlay will require to declare dependency (at least as compile)
Is it ok to have only dependency for slf4j api? How to package other dependencies to war without declaring them as project dependencies?
Thanks!
Please simply specify dependency to slf4j-log4j in runtime scope.
So during compile and test time class from runtime scope will not be available.
Also in IDE it shouldn't be visible - I checked it in IntelliJ.
Of course all artifacts with runtime scope will be put in WEB-INF/lib directory.
Example:
...
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
<scope>runtime</scope>
</dependency>
...

#Webservice annotation exception on weblogic

I am trying to run my application which contain JAX WS (2.1) Webservice using JDeveloper 11g R2(11.1.2.3.0) in JDK 1.6.0_31-b05. The error is coming from #WebService annotation present on the class.
When I am running the application, I am getting below error,
java.lang.IllegalArgumentException: Argument(s) "type" can't be null.
at com.sun.xml.bind.api.TypeReference.<init>(TypeReference.java:89)
at com.sun.xml.ws.model.RuntimeModeler.processDocWrappedMethod(RuntimeModeler.java:758)
at com.sun.xml.ws.model.RuntimeModeler.processMethod(RuntimeModeler.java:678)
at com.sun.xml.ws.model.RuntimeModeler.processClass(RuntimeModeler.java:428)
at com.sun.xml.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:277)
at com.sun.xml.ws.server.EndpointFactory.createSEIModel(EndpointFactory.java:363)
at com.sun.xml.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:202)
at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:496)
at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:539)
at weblogic.wsee.jaxws.JAXWSDeployedServlet.getEndpoint(JAXWSDeployedServlet.java:183)
It seems that embedded Web Logic is using the internal libraries instead of provided one from JDK. The classes RuntimeModeler or TypeReference are present in JDK rt.jar starts with package com.sun.xml.ws.internal. Weblogic is picking these classes from glassfish.jaxb_1.0.0.0_2-1-12.jar & glassfish.jaxws.rt_1.2.0.0_2-1-5.jar, but these jars are not part of my application.
I have already used weblogic.xml with below tag,
<prefer-web-inf-classes>true</prefer-web-inf-classes>
I tried adding jaxws-api.jar & jws-api.jar in DefaultDomain/lib directory, but that didn't work
Any clue how to resolve this exception or how to force weblogic to use jdk runtime classes? The same application work properly on stand alone weblogic.
I had the same problem and found the answer here: http://www.intropro.com/resources/blog/66-argument-s-type-can-t-be-null
In short - the problem appears because you have jaxb-impl in you classpath which overrides WebLogics own jaxb, You may not explicitly refer to this dependency from your pom.xml, but some of your other dependencies do.
In my case I had apache-cxf as maven dependency and it had jaxb 2.1.13 as sub-dependency with scope "compile". All I had to do is exclude this apaches jaxb and add my own dependency with scope "provided" to explicitly use WebLogics jaxb.
in pom.xml it looked like this:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>2.7.2</version>
<exclusions>
<exclusion>
<artifactId>jaxb-impl</artifactId>
<groupId>com.sun.xml.bind</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<scope>provided</scope>
<version>2.1.13</version>
</dependency>
You can use eclipses "Dependency Hierarchy" tab in pom.xml view or simply command line "mvn dependency:tree" to find out how jaxb-impl made it to your classpath.
In my case, i had a typo in the arguments of the operation, where two arguments had the same webParam name. Modified that and deployed, issue was resolved.
Have you tried listing the correct jar in the manifest class-path: attribute? You could also put the jdk classes in the app and try using a FilteringClassLoader to specify which classes to use from the app rather than system classloader.
http://docs.oracle.com/cd/E15051_01/wls/docs103/programming/classloading.html#wp1097263

Resources