In a test WebSocket application using Atmosphere servlet I'm getting the following exception:
SEVERE: Servlet.service() for servlet AtmosphereServlet threw exception
java.lang.ClassNotFoundException: javax.servlet.AsyncContext
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1645)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1491)
at org.atmosphere.cpr.AtmosphereServlet.doPost(AtmosphereServlet.java:191)
at org.atmosphere.cpr.AtmosphereServlet.doGet(AtmosphereServlet.java:177)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
From the below posts I understand that this might be caused by a Servlet container version older than Servlet 3.0:
ClassNotFoundException: javax.servlet.AsyncContext in Jetty hello world
ClassNotFoundException: javax.servlet.AsyncContext in Jetty hello world in eclipse
Grails project - Servlet call - ClassNotFoundException: javax.servlet.AsyncContext
However the application is running on Tomcat7, and the following dependency is added in pom.xml:
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
I've checked all other dependensies in the project and was not able to find anything else related to Servlet. Still I'm getting the exception.
Questions: How to find a jar file which is actually used by the application? How to find the dependency which is causing the usage of an old version?
I was finally able to solve the dependency conflict by doing the following.
To find the jar file which is used by application I used the below simple code:
public void listJarFilesAndClassVersions() {
Class classToCheck = javax.servlet.ServletRequestWrapper.class;
URL location = classToCheck.getResource('/'
+ classToCheck.getName().replace('.', '/') + ".class");
System.out.println(location.toString());
for(Package p : Package.getPackages()) {
if (p.getName().startsWith("javax.servlet")) {
System.out.println("Class: " + p.getName()
+ ", version: " + p.getSpecificationVersion());
}
}
}
The class javax.servlet.ServletRequestWrapper was chosen because it does exist in the old Servlet 2.5.
The execution of the above script gives me the following:
jar:file:/C:/Users/[username]/.m2/repository/org/apache/tomcat/servlet-api/6.0.29/servlet-api-6.0.29.jar!/javax/servlet/ServletRequestWrapper.class
Class: javax.servlet.jsp, version: 2.1
Class: javax.servlet, version: 2.5
Class: javax.servlet.http, version: null
So, first, it confirms that the Servlet of version 2.5 is used, and second, the "bad" jar is located in the maven repository under the tomcat directory.
After a short reasearch I was finally able to find the root cause of that: when deploying and running the maven application I need to specify the concrete version of tomcat, otherwise maven uses the libraries from tomcat of version 6. So the fix for me was to change
mvn -Dmaven.tomcat.port=8080 tomcat:run-war
to
mvn -Dmaven.tomcat.port=8080 tomcat7:run-war
Now if I execute the above script it gives the following result:
jar:file:/C:/Users/[username]/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/7.0.47/tomcat-embed-core-7.0.47.jar!/javax/servlet/ServletRequestWrapper.class
Class: javax.servlet.jsp, version: 2.2
Class: javax.servlet, version: 7.0
Class: javax.servlet.http, version: 7.0
Class: javax.servlet.annotation, version: 7.0
Class: javax.servlet.descriptor, version: 7.0
Hope it helps others who is running into the same issue.
There're two ways in which I usually find a conflict.
If you are using Eclipse, open the pom.xml in IDE, and switch to "Dependency Hierarchy" tab. In the left panel is the dependency tree, and in the right panel are the dependencies actually getting used. Right after each dependency it's its scope (eg. compile / test / runtime / omitted for conflict)
In terminal run the command. mvn dependency:tree It will print out the dependency like in Eclipse.
Related
With the recent announcement of support for Servlet 3.1, I cannot figure out how to modify the App Engine Standard environment to use 3.1 instead of 2.5 in a non-Maven build.
It seems there is no way to upgrade to 3.1?
https://cloudplatform.googleblog.com/2017/06/Google-App-Engine-standard-now-supports-Java-8.html
Here is a full example given here: https://github.com/GoogleCloudPlatform/getting-started-java/tree/master/appengine-standard-java8/helloworld
Running procedure is also attached.
For Gradle Users:
For non-maven users, you can use gradle.
In gradle build file, line number 39 denotes: https://github.com/GoogleCloudPlatform/getting-started-java/blob/master/appengine-standard-java8/helloworld/build.gradle#L39
providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
Running locally:
gradle appengineRun
If you do not have gradle installed, you can run using ./gradlew appengineRun.
To use visit: http://localhost:8080/
For Maven Users
In pom.xml, line number 62 to 70 denotes that it is using servlet version 3.1.0: https://github.com/GoogleCloudPlatform/getting-started-java/blob/master/appengine-standard-java8/helloworld/pom.xml#L66
<!-- [START servlet] -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
<!-- [END servlet] -->
Hope it will clarify you.
These are the steps that should work no matter what technique is used, as long as it produces a valid war that includes javax.servlet-api:3.1.0:
1) As documented, make sure you've added <runtime>java8</runtime> to your appengine-web.xml file
2) uncompress the war into its own separate directory
3) deploy using the appcfg.sh script found on App Engine SDK for Java bin directory. It will look something like:
/<some-path>/appengine-java-sdk-1.9.54/bin/appcfg.sh update /<some-path>/exploded-war/
Note: To verify ServletContext's version from within a servlet I've used:
ServletContext sc = req.getSession().getServletContext();
resp.getWriter().println("Servlet version = " + sc.getMajorVersion() + "." + sc.getMinorVersion());
15:28:38.716 [qtp1588771273-32] WARN o.e.jetty.servlet.ServletHandler - /tp/gremlin/execute
java.lang.IllegalArgumentException: Could not resolve dependency of type:javax.transaction.TransactionManager
at org.neo4j.graphdb.DependencyResolver$Adapter$1.select(DependencyResolver.java:87) ~[neo4j-kernel-2.2.9.jar:2.2.9]
at org.neo4j.kernel.extension.KernelExtensions.resolveDependency(KernelExtensions.java:112) ~[neo4j-kernel-2.2.9.jar:2.2.9]
This is from Neo4j 2.x (the Gremlin plug-in). The package, when built and deployed as instructed at https://github.com/thinkaurelius/neo4j-gremlin-plugin, does contain the jar-file which describes this class, and Maven did download it and did install it there. But, when the server attempts to load and execute the extension, nothing is resolved.
Why?
Currently I'm working with EJB services running on Weblogic 12c Server. When I write a JUnit test to call EJB services, an error appears with:
java.lang.NoClassDefFoundError:
weblogic/i18n/logging/MessageLoggerRegistryListener
Anyone knows where is this class from? I googled it but got no result.
This class can be found in the /wlserver/modules/features/weblogic.server.merged.jar and in the /wlserver/server/lib/wlclient.jar files.
Additionally if you are doing this in a maven project, and you're using the Oracle Maven repository, you can use
<dependency>
<groupId>com.oracle.weblogic</groupId>
<artifactId>wlclient</artifactId>
<version>12.1.3-0-0</version>
<scope>provided</scope>
</dependency>
Set WL_HOME in your environment variable correctly:
Variable name: WL_HOME
Variable value:
your weblogic 12c installation path like: C:/Oracle/Middleware/Oracle_Home/wlserver/server
I've this wired java compilation error when I start jetty. I'm running naven build and it gives me success, however when i run the mvn jetty:run command, it gives the following error:
EXCEPTION org.apache.jasper.JasperException: PWC6033: Error in Javac compilation for JSP||PWC6199: Generated servlet error:|org.apache.jsp.tag.web.ui.static_tag is not abstract and does not override abstract method getDependants() in org.apache.jasper.runtime.JspSourceDependent||PWC6199: Generated servlet error:|getDependants() in org.apache.jsp.tag.web.ui.static_tag cannot implement getDependants() in org.apache.jasper.runtime.JspSourceDependent| return type java.util.List<java.lang.String> is not compatible with java.util.Map<java.lang.String,java.lang.Long>||
at org.apache.jasper.compiler.DefaultErrorHandler.javacError(DefaultErrorHandler.java:129)
at org.apache.jasper.compiler.ErrorDispatcher.javacError(ErrorDispatcher.java:299)
at org.apache.jasper.compiler.Compiler.generateClass(Compiler.java:392)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:453)
I'm using the maven-jetty-plugin for running jetty.
I've tried re-installing the environment that I'm currently working, and also checkout my project ina different directory. Nothing has worked so far. Does have nay ideas what might have gone wrong?
Your problem would be one of the followings:
You have a dependency to glassfish in your pom.xml: This was the problem in my case
You are using a different version of servlet-api than your jetty uses. To solve this you can add provided tag to your servlet-api dependency that makes the jetty to use its own servlet version:
javax.servlet
servlet-api
3.2
provided
Using the latest Jetty plugin helped me
http://www.eclipse.org/jetty/documentation/current/jetty-maven-plugin.html
this link points to the root cause of the problem
https://support.lucidworks.com/hc/en-us/articles/201784186-Error-in-Javac-compilation-for-JSP-in-LucidWorks-Search-UI
FYI my plugin configuration
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.3.7.v20160115</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
</configuration>
</plugin>
I updated a project that was using struts 2.2.3.1 to the 2.3.1.2 in the pom.xml file. After running maven it picked up the jar from the repo and all that and built the package just fine. But, when I run the webapp I am getting this error:
2012-04-26 13:42:06,300 ERROR org.apache.struts2.dispatcher.Dispatcher.error:38 - Dispatcher initialization faile Unable to load configuration. - bean - jar:file:/Library/Tomcat/apache-tomcat-6.0.35/webapps/idmadmin/WEB-INF/lib/struts2-core-2.3.1.2.jar!/struts-default.xml:29:72.....
I was thinking that maybe the old one was still stuck in the classpath but I don't see it.