Running Clojure Code in Tomcat - java

I'm trying to run a portlet in a Liferay Container that runs Apache Tomcat 7.0.59. The portlet refers to Clojure code in one of several fashions:
1) :gen-class :impl-ns ( this namespace is aot compiled, the impl-ns namespace is not )
2) Clojure.var("clojure.core", "require").invoke(Clojure.read(ns)); then calling invoke on returned IFN ( ns is also a non aot compiled namespace )
3) ring uberwar ( this is not a portlet )
The one I am most concerned with is the first one, but in all cases, while the leiningen test all pass (and it's calling the code the portlet is calling) I get frequent but intermittent errors while either starting up tomcat with the portlet/servlet deployed or while doing a hot deploy. The errors are symbol resolution errors in code I've unit tested and the unit test are passing:
at clojure.lang.RT.loadResourceScript(RT.java:370)
at clojure.lang.RT.loadResourceScript(RT.java:361)
at clojure.lang.RT.load(RT.java:440)
at clojure.lang.RT.load(RT.java:411)
at clojure.core$load$fn__5066.invoke(core.clj:5641)
at clojure.core$load.doInvoke(core.clj:5640)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.lang.Var.invoke(Var.java:379)
at portal_aot_common.CljJobManager.<clinit>(Unknown Source)
... 238 more
Caused by: java.lang.RuntimeException: Unable to resolve symbol: map->obj in this context
at clojure.lang.Util.runtimeException(Util.java:221)
at clojure.lang.Compiler.resolveIn(Compiler.java:6940)
at clojure.lang.Compiler.resolve(Compiler.java:6884)
at clojure.lang.Compiler.analyzeSymbol(Compiler.java:6845)
at clojure.lang.Compiler.analyze(Compiler.java:6427)
... 285 more
The code is not in the WEB-INF/classes directory or a jar in the WEB-INF/lib directory; instead I opted to modify the catalina.properties file and include the src path in the common.loader property. I've also tried using tomcat 7's virtualwebapploader virtualClasspath attribute.
The problem is that when it works, it works completely. But there always seems to be a 50/50 chance that it doesn't work and i get the above error. The code is not in jar (I like being able to modify the code and restart the server without having to install or build anything).
For the ring uberwar, the problem seems to be that the servlet cannot find the handler class on tomcat startup, but seems to be ok when I build the war and do a hot deploy. lein ring server works fine, but actually deploying seems to have a 50/50 chance of success.
I'm using clojure 1.6.0 and java 8.
Any ideas on what might be happening would be appreciated.

Related

I got `NoClassDefFoundError` on one machine but the same jar works fine on another machine

I have packaged my netty project as a jar, and it works fine locally and on one server, but it will throw java.lang.NoClassDefFoundError exception on another one. Furthermore, if I start the jar with java from jre instead of java comes with jdk (same version), it works again.
If this jar works somewhere, it means the jar has already had the required classes packaged, then what might cause the problem?
2022-06-30 10:58:11 WARN [io.netty.channel.DefaultChannelPipeline] : An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
java.lang.NoClassDefFoundError: Could not initialize class com.baidu.bjf.remoting.protobuf.utils.JDKCompilerHelper
at com.baidu.bjf.remoting.protobuf.ProtobufProxy.doCreate(ProtobufProxy.java:397)
at com.baidu.bjf.remoting.protobuf.ProtobufProxy.create(ProtobufProxy.java:311)
at com.baidu.bjf.remoting.protobuf.ProtobufProxy.create(ProtobufProxy.java:276)
at com.baidu.bjf.remoting.protobuf.ProtobufProxy.create(ProtobufProxy.java:249)
at com.baidu.bjf.remoting.protobuf.ProtobufProxy.create(ProtobufProxy.java:208)
at com.wjserver.ws.codec.ProtobufDecoder.decode(ProtobufDecoder.java:23)
at com.wjserver.ws.codec.ProtobufDecoder.decode(ProtobufDecoder.java:40)
at com.wjserver.ws.handler.WebSocketInHandler.channelRead0(WebSocketInHandler.java:41)
...

Optaplanner - The Website resource does not exist

I'm making a runnable jar for my project, and i keep getting this error when it starts generating the benchmark report:
Exception in thread "main" java.lang.IllegalStateException: The websiteResource (twitterbootstrap/css/bootstrap-responsive.css) does not exist.
at org.optaplanner.benchmark.impl.report.WebsiteResourceUtils.copyResource(WebsiteR esourceUtils.java:57)
at org.optaplanner.benchmark.impl.report.WebsiteResourceUtils.copyResourcesTo(WebsiteResourceUtils.java:33)
at org.optaplanner.benchmark.impl.report.BenchmarkReport.writeHtmlOverviewFile(BenchmarkReport.java:738)
at org.optaplanner.benchmark.impl.report.BenchmarkReport.writeReport(BenchmarkReport.java:287)
at org.optaplanner.benchmark.impl.DefaultPlannerBenchmark.benchmarkingEnded(DefaultPlannerBenchmark.java:315)
at org.optaplanner.benchmark.impl.DefaultPlannerBenchmark.benchmark(DefaultPlannerBenchmark.java:109)
Everything else works fine since i added "resources/" infront of the drools and the benchmarkConfig paths.
Since there are a few more resources just for the benchmark, i probably would need to do the same for them also.
How can i get access to the resources for the benchmarks?
Sounds like you're building from source with an IDE (Eclipse/IntelliJ/NetBeans/...) and your project isn't set up correctly to also copy *.css files as classpath resources (so it has a specific exclude for css somewhere).
With a modern IntelliJ IDEA version, opening the pom.xml file, this definitely doesn't happen. With a modern Eclipse/NetBeans version, I'd presume the same.

FAIL - Deployed application at context path / but context failed to start

Im working in 2 separate webapplications a back and front app.
The funny thing is when I run the back-end I don't have any issues. But in the front-end I get the following error:
I have the following error in Netbeans
NetBeans: Deploying on Apache Tomcat or TomEE
profile mode: false
debug mode: false
force redeploy: true
Undeploying ...
undeploy?path=/
OK - Undeployed application at context path /
In-place deployment at D:\WebDevel\WebStore\WebFrontE\target\Web-1.0-SNAPSHOT
Deployment is in progress...
deploy?config=file%3A%2FC%3A%2FUsers%7E1%2FAppData%2FLocal%2FTemp%2Fcontext7815575477480252472.xml&path=/
FAIL - Deployed application at context path / but context failed to start
Both are running on the same Tomcat. my colleague has the same code and it works fine :-s
Context Path (or) Context Root must be unique for each application deployed on the server.
So you can't deploy two applications with same context root to the same server. It seems for both of your applications the context path is /.
Check server.xml to see what context path both of them have. If they are not unique, then change them to solve the problem.
But if you want the same context root for both applications, then you need to deploy them in two different servers.
For more information:
Tomcat Context paths configuration
I may be a little late but would say that this could be because of the change in the factory name in Tomcat 8. So follow the below steps:
1) First, see if you are using Tomcat 8 or higher.
2) If yes, and tomcat is not able to deploy your application. Run the application in Debug mode and see stack trace in Tomcat window (at bottom. Not same as Tomcat.log). Scroll down the window and see if you can find an Exception like this:
Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory
3) If you see something like above, Open your META-INF/context.xml and replace or add the factory attribute in the resource tag with:
factory="org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory"
4) Restart tomcat and redeploy.
While trying to deploy a spring boot web app from jenkins to an external VM I was getting the same error as below.
After I look into tomcat log I found it was for java version error. I didnt install proper java version which my spring boot application supports.
I installed openjdk 8 and removed java7 from vm and it was resolved.
The actual cause behind the below error can be many . so check your tomcat /logs/catalina.out directory for exact error. at Jenkins build log it doesn't give actual error.
FAIL - Deployed application at context path [/webapp] but context
https://www.youtube.com/watch?v=1jsKGhXmm4c
I had this problem a d after a lot of links that didn't work, found this solution. Edit the server.xml on your Tomee server to provide a fully qualified path for appBase:
<Host name="localhost" appBase="C:\apache\apache-tomee-7.0.2-plume\webapps"
unpackWARs="true" autoDeploy="true">
The following error occurs if your context has not started well.
Instance : You have context listener that calls a method and the method is not present.
My issue was a syntax error in web.xml, I didn't close an element
The tomcat window (NetBeans) had a clear errormessage, thanks Arafat
01-Sep-2018 17:34:38.641 SEVERE [http-nio-8080-exec-5] org.apache.tomcat.util.digester.Digester.fatalError Parse Fatal Error at line 50 column 11: The element type "param-value" must be terminated by the matching end-tag "".
I am also had trouble solving this kind of issue on my netbeans. I'm stack the whole day getting rid of this issue. Many solutions have been tried but still nothing happen until I tried to delete the "target" folder of my project and that solved the problem! Hope it helps! :)
I have came across this problems several times,i tried the below steps and it worked..!
1. Backup you current project(For safety).
2. Locate you project folder location (Normally found in MyDocuments or Documents folder named as NetBeansProjects).
3. Open the project folder and delete the folder named target inside your project folder
4. Close the NetBeans and re-open the it and run the project.
And you are good to go.
If the above didn't work then try deleting the xml file from the folder "Tomcat 9.0\conf\Catalina\localhost" folder.
I had this error while using Java Web due to a syntax error:
My Servlet code should be like this:
#WebServlet(name = "EleicaoServlet", urlPatterns = {"/EleicaoServlet", "/main", "/insert", "/edit", "/delete", "/update"})
But I forgot to type '/' in the "/update"
#WebServlet(name = "EleicaoServlet", urlPatterns = {"/EleicaoServlet", "/main", "/insert", "/edit", "/delete", "update"})
And I got this error.
So if nothing above works you may want to check your code, it can be something stupid like this.
I have tried
mvn clean install
and worked for me for the same problem :)
'undeployed application at context path' this error occur due to missing some file while copying project from one system to another.
while coping make sure all files should be copied.If an error occur then please recopy project and import it..
It may work..
I just had the same issue i solved by giving security permission to the user for Apache Server Foundation in root folder
in my case i removed some configuration tags that i added in web.xml,trying to configure a strut package.I also removed that package respectively,i restarted the server,run the project and it worked.
Faced the same problem # one time. In one of the instance, it was caused by a controller that had multiple methods with same route e.g
#RestController
public class UsersController
{
#Autowired
UsersInterface userInterface;
#RequestMapping(value = "/get", method = RequestMethod.GET)
public String test()
{
return "Users";
}
#RequestMapping(value = "/get", method = RequestMethod.GET)
public List<user> getUsers()
{
List<User> users = userInterface.getUsers();
return users;
}
}
As you can see, the controller has 2 methods that define two get routes, hence Spring cannot resolve the method to run the .../users/get route.
Remote one of the get routes and change it to something else.
I may be late to answer but might help others later in the future.
This could be many causes, but the most frequent personally in my case was the web.xml file servlet declarations. When I was cross developing a project both on Mac and Linux, I saw the file behave different in the two platforms due to some space or new line issues. It took me hours to find out as the servlet count was more than 20. Ultimately I narrowed down to strangely only one controller class declaration and found the syntax to be absolutely perfect. It bamboozled me, so I thought I'd rewrite the declaration after deleting the old one and BAM! It worked on Mac immediately. Strange.
I am facing this problem, after trying several other suggestions, the following thing worked perfectly for me.
Delete the following file:
/apache-tomcat-9.0.13/conf/Catalina/localhost/*.xml
This is a bit late but for anyone who might face the same error.
For me, this error was caused by wrong syntax in my servlet.
#WebServlet(urlPatterns = {"/x/login", "/x/register", "/x/logout", "x/createrestaurant"})
It looked like the above and I got the same error. After sometime and trying to deploy on a different server (from Tomcat to Glassfish), Glassfish gave me better logs and I realized the syntax should have been like this
#WebServlet(urlPatterns = {"/x/login", "/x/register", "/x/logout", "/x/createrestaurant"}).
Notice the / before x/createrestaurant.
I had the same issue with even newly added projects tried a lot of stuff mentioned above. what works for me is to manually Stop tomcat service in the Installation directory \Tomcat 9.0\bin Tomcat9w.exe. Then deployed the project it works this way in Netbeans IDE.
FAIL - Failed to deploy application at context path...
I was facing the same issue. But I resolved it. Please see the following steps:
First, stop the Tomcat service that is already running on the background, Not in the Netbeans. For this, go to TaskManager properties>Services>tomcat
Right click on the tomcat service to stop
Now, after that. Close netbeans IDE and run again
Right click on the project and select run. The project will be running without any issue
I hope above solution will be helpfull who having the same error.
One Problem could be the port you are trying to use might be being used by another application. Try changing the port or clearing that one and it might work fine.
Problem has been resolved by stopping the Tomcat server
sudo systemctl stop tomcat
so as to allow Netbeans to run it. If the server is already running when Netbeans tries to deploy an app Netbeans will display the delopy failed message.
I had the same problem, but I used only maven (without IDE). My tomcat version was tomcat7 7.0.70-1 and jdk8 (in pom.xml: <java.version>1.8</java.version>) It turned out that tomcat7 incompatible with java 8, so, I changed java.version in pom.xml on <java.version>1.7</java.version> and that was the solution!
I had same problem and I resolved this issue by stopping the tomcat from IDE and run the web application it starts the tomcat automatically.(This works in Netbeans IDE). Simply Stop Tomcat and start again and redeploy web application.

Hibernate in Servlet causesNoClassDefFoundError: org/slf4j/LoggerFactory

I have a Java (6) application which uses Hibernate (V3.3.2) to read data from HSQLDB, which i build and debug/run with Eclipse (V3.5.1), and it works fine.
I then created a GWT (V1.7) Servlet web app, copied my hibernate classes into it, and added the same User Libraries dependencies. However when i run the servlet and try to access a URL which invokes my code i get this:
java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
at org.hibernate.cfg.Configuration.<clinit>(Configuration.java:152)
at xxx.daoimpl.DAOSession.initialise(DAOSession.java:40)
where DAOSession.java:40 is :
AnnotationConfiguration config = new AnnotationConfiguration ();
Googling for this error suggests i am missing slf4j-api.jar from the classpath, however if i look at the command line for the Debug properties i can see this jar there:
C:\java\jsedk_6\jre\bin\javaw.exe
-agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:54541
-Xmx512m -Dfile.encoding=Cp1252
-classpath
D:\dev\workspace\xxx\src;
D:\dev\workspace\xxx\resources;
D:\dev\workspace\xxx\war\WEB-INF\classes;
C:\java\eclipse\plugins\com.google.gwt.eclipse.sdkbundle.win32_1.7.1.v200909221731\gwt-windows-1.7.1\gwt-user.jar;
C:\java\eclipse\plugins\com.google.gwt.eclipse.sdkbundle.win32_1.7.1.v200909221731\gwt-windows-1.7.1\gwt-dev-windows.jar;
C:\java\hibernate-annotations-3.4.0.GA\hibernate-annotations.jar;
C:\java\hibernate-annotations-3.4.0.GA\lib\ejb3-persistence.jar;
C:\java\hibernate-annotations-3.4.0.GA\lib\hibernate-commons-annotations.jar;
C:\java\hibernate-distribution-3.3.2.GA\hibernate3.jar;
C:\java\hibernate-distribution-3.3.2.GA\lib\required\antlr-2.7.6.jar;
C:\java\hibernate-distribution-3.3.2.GA\lib\required\commons-collections-3.1.jar;
C:\java\hibernate-distribution-3.3.2.GA\lib\required\dom4j-1.6.1.jar;
C:\java\hibernate-distribution-3.3.2.GA\lib\required\javassist-3.9.0.GA.jar;
C:\java\hibernate-distribution-3.3.2.GA\lib\required\jta-1.1.jar;
C:\java\hibernate-validator-4.0.1.GA\hibernate-validator-4.0.1.GA.jar;
C:\java\hibernate-validator-4.0.1.GA\lib\validation-api-1.0.0.GA.jar;
C:\java\hibernate-validator-4.0.1.GA\lib\log4j-1.2.14.jar;
C:\java\hsqldb\lib\hsqldb.jar;
C:\java\restlet-jse-2.0m5\lib\org.restlet.jar;
C:\java\restlet-jee-2.0m5\lib\org.restlet.ext.servlet.jar;
C:\java\restlet-jse-2.0m5\lib\org.restlet.ext.xml.jar;
C:\java\slf4j-1.5.8\slf4j-api-1.5.8.jar;
C:\java\slf4j-1.5.8\slf4j-log4j12-1.5.8.jar
com.google.gwt.dev.HostedMode
...
If i open the jar i can see the LoggerFactory class in there.
Any idea why it isn't being found by the class loader?
Edit 1: If try to access org.slf4j.LoggerFactory from my code, Eclipse compiles it ok, but i get the same error at runtime.
Edit 2: If i add a Test class with a main which calls the same code and run it, it works. So this classpath problem seems specific to the Servlet.
thanks,
jon
It seems that copying the two slf4j jars to the war/WEB-INF/lib sub-project/dir fixed the problem. I'm not really sure why i should need to do this for these two jars and not for all the other Hibernate, Restlet etc jars that the project also uses, though i suppose for consistency i will do that anyway - i guess it will make deployment easier as well.
If someone can provide some sort of explanation as to why this worked and why exactly i need to do it i will select it as the "correct" answer, otherwise i'll select this one.
Can you please reconfirm that you have at least two slf4j.jar files in the classpath, the slf4j-api.jar and exactly one implementation, such as slf4j-jdk14.jar?
You must not have multiple sflj4-implementations in the classpath.
You have a runtime dependency issue so everything compiles fine but the dependency is in your jars. You need to visit the Hibernate site and look at the compatibility matrix and make sure you are matched up correctly then check the dependencies for annotations and core. You log4J jars look fine so it's definitely some quirk.
If it works in Eclipse then logically it's definitely some diff between the 2 runtimes (eclipse and non-eclipse), if the matrix checks out fine then see if you can factor out the commonalities in the 2 then work out the differences -- your answer should be in there.
I had a similar issue except I was using Tomcat and the NoClassDefFound error was on the juli logger. I fixed it by removing the Tomcat dependencies from my classpath when running in hosted mode because hosted mode embeds a Tomcat server that was conflicting. So I would see what happens if you remove some or all of the restlet jars from your classpath to see if they conflict.

Overriding application server behaviour for loading jsp-api and servlet-api jars in a packaged web application

I have a project built and packaged with a specific version of jsp-apiand servlet-api jar files. Now I want these jars to be loaded when deploying the web project on any application server for example tomcat, WAS, Weblogic etc.
The behaviour I have seen on tomcat is that it gives messages that the packaged version of these apis are not loaded along with an offending class.
Is there any way I could override these server settings or behaviour?
My concern is that letting the default behaviour of a server may allow different behaviour on different servers or even on different versions of same app server.
If you have control over the server where you want to install this webapp you can replace the core jars with yours.
Additionally you can prepend the jars in the startup of the app server.
Update:
As for the second part, you'll need to modify the startup file of the application server it self.
I don't have an installation at hand but lets suppose in the dir $YOUR_APPSERV/bin there are a bunch of scripts ( either .cmd or .sh files )
Some of them start the app server , some other help to configure it.
You need to modify one of those in such a way the command line look like this:
(assume a windows installation)
java -Xbootclasspath/p:c:\cutomjars\myJar.jar;customjars\myOtherJar.jar ..................... // the rest of the normal command line.
-bootclasspath/p prepends the jars to the app classpath
-bootclasspath/a appends the jars to the app claspath
This option let you override any class in the JVM with those specified in the jars, so you can even substitute java.lang.String if you want to.
That's one approach. Unfortunately -Xbootclasspath is an option for Sun JVM ( that is JRockit does not have it, nor the IBM's VM what ever his name is )
There was another option where you declare a folder where all the extensions are. Plus, there is an ext directory in the jre.
Take a deep dive into your application server bin directory and find out what each script is used for, I'm pretty sure you'll make it through.
Here's a more formal explanation of this topic: http://java.sun.com/j2se/1.5.0/docs/tooldocs/findingclasses.html
I hope it helps.
BTW, I use to do this years ago, to substitue the CORBA package with a veeeery old version. So this works for sure.
I've split the answer in two for clarity
Tushu, I have two news for you.
The good one is I've managed to replace the servlet api from 2.5 to 2.3 in my tomcat using the steps I've described you in my previous post( screeshots below )
The bad new ( and I should've guessed this before ) The tomcat won't start.That's obvious, the servlet-api.jar is the core of the tomcat, and the version depends on some features present there. If it is changed, the engine won't work.
The solution I've show you, works to change the behavior of one or two classes, but not to substitute the whole system.
So , the only options you have are:
Run on a servlet container that meets your servlet specification
Upgrade your app
Test it as it is on the new spec. Chances are ( and if you didn't link to non public classes ) your app still work
( I did this in the past ) create a new jar with exactly the classes needed ( let's say your app only needs one class to run well ) and then prepend that class to the container.
Here's the test jsp
Servlet version: <%=application.getMajorVersion()%>.<%=application.getMinorVersion()%>
Output with unmodified version:
unmodified version http://img89.imageshack.us/img89/9822/87694136ld9.png
Modified version:
modified version http://img241.imageshack.us/img241/7842/86370197ev3.png
Screenshot of the modified catalina startup
diff ouput http://img246.imageshack.us/img246/3333/30172332tp7.png
Tomcat stacktrace
SEVERE: Servlet.service() for servlet jsp threw exception
javax.servlet.ServletException: javax.servlet.jsp.JspFactory.getJspApplicationContext(Ljavax/servlet/ServletContext;)Ljavax/servlet/jsp/JspApplicationContext;
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:275)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
JRockit can use -Xbootclasspath. See the command line reference
Other option is to use
-Djava.endorsed.dirs
Upon JVM startup

Categories

Resources