Instead of using a certain jar in my WEB-INF/lib folder, I want to use its source code (same directory structure and everything) in my WEB-INF/classes folder, so that I may be able to modify its classes more story.
Yet (re)starting my tomcat after deleting the original jar and uploading the corresponding directory into WEB-INF/classes gives me the following error:
SEVERE: Error configuring application listener of class no.something.something1.http.LifecycleListener
java.lang.ClassNotFoundException: no.something.something1.http.LifecycleListener
I am certain that the directory path is the same as the one inside the jar. Also, I have previously tried using classes in my WEB-INF folder for this web application, and tomcat has also been unable to load them, for some reason.
Does anyone know how I go about troubleshooting this error?
Tomcat can only load .class files, it doesn't know what to do with raw source code files. Tomcat doesn't do hot loading of .class files like that anyway. You would have to restart the application or server after you recompiled them either way, packaging them as a .war isn't that much of a burden either way once you automate it.
If you take the time to automate the build and deployment of a proper .war you can just rebuild the .war and it will automagically undeploy and redeploy the application itself, which is many times faster than restarting the entire server.
You can't do what you are trying to do the way you are trying to do it. Tools like JRebel address these issues, but I don't find them as useful as their marketing makes them sound.
You could use embedded tomcat (or embedded jetty) to map directory structure of the application as you like. It probably will require some tinkering if you need some JNDI resources within your application but still worth the trouble.
Here's an example
Related
I am unable to find another article that solves my problem but am happy to hear about one if you know the answer.
I have a RESTful service built in Java with Eclipse. It uses Spring and all of its bells and whistles.
After much work with configuration files, I am able to build the service into a war file, deploy it to my Tomcat webapps folder, and run it from standalone Tomcat. However, it still throws several errors on start when I try to start it from a service defined within Eclipse. The errors are the same errors that I was seeing before I got the config files correct for standalone Tomcat. The errors are about the inability to create the required beans because of references to properties that can't be found.
How did I get it running in Tomcat? I added a couple of .properties files to define properties needed by the beans that get launched at startup and then added a 'set CLASSPATH=...' line to the setenv.bat file in the Tomcat bin folder. This new line adds the properties files into the CLASSPATH. That seems to have fixed everything from standalone Tomcat.
So, my question is, "How do I make these same changes inside my Eclipse server?" I have added the properties folder with the property files under the config folder in Eclipse, just like it is in my native Tomcat folders, but I do not know how to modify the CLASSPATH string to specifically point to my .properties files (as I have done in the setenv.bat file for standalone Tomcat).
I think I understand the problem, but have no idea about the solution.
Thanks for listening.
Dave
Eclipse does not use any *.sh/*.bat files to startup Tomcat. In order to modify the way the server is started you have to open the configuration UI of the server by double-clicking on the server in the Servers view.
From there you will be able to modify the classpath of the system classloader through "Open launch configuration".
Another important setting is "Server path" which tells Eclipse, the value of $CATALINA_BASE. You can modify it only after removing all modules and cleaning the server. It is useful to set it to an easily accessible directory: this way you can verify directly that Eclipse didn't mess up your application deployment (sometimes it "forgets" to copy some libraries).
The "Configuration path" setting tells Eclipse where to find the files (but not subdirectories) that will be copied into $CATALINA_BASE/conf.
Remark: if your application requires you to add libraries to the top classloader, there is probably a problem in your project. The "missing" libraries should be added to WEB-INF/lib of your application instead: look into the "Deployment assembly" of your Eclipse project configuration.
Hi In my project I have many many jars.
Every time I change code and need to upload it to the server takes very long time, because I m adding the jars to the war to be deploy on tomcat.
I m trying to put all the jars in the server, in some folder and to upload the rest of the project only, to speed the cycle.
What will be the best way of doing that ?
I m using tomcat 8.5 also for production deployment without any build tool.
I would like to set an ABSOLUTE path in the classpath but when doing that in my local machine it won't work after deployment to the unix server.
I never saw where or if I can set an absolute path for the jars (NOT OF THE LOCAL MACHINE)
Thanks in advance
You can read about this in Tomcat docs: Class Loader HOW-TO.
The most simple case and way - put these commonly used jars into $CATALINA_BASE/lib dir - they will be loaded by Tomcat class loader.
But, it doesn't seems to be very nice practice, as mentioned tutorials claims:
Normally, application classes should NOT be placed here.
Personally me, in practice purposes, I would ignore this hint and still place jars inside this folder. But if you want to be accurate, you could create separate path on server (or even inside CATALINA_BASE folder) and place jars there. After that you have to specify this path in $CATALINA_BASE/conf/catalina.propertiesfile in common.loader property:
common.loader="${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar"
I have installed and configured tomcat+solr on my personal linux machine and windows as well. I was able to get them working fine. I'm very new to Java and how the file structure works. (i.e. knowing where to put war files and what WEB-INF is) So now that I am ready to install solr and configure it on my clients shared hosting plan, the directions are different from what I did before. I dont want to mess this up and apparently the webserver reboots daily and I dont think I can do it manually which means I have one shot at this every day.
Here is the directions for installing a tomcat servlet on his hosting provider:
http://www.apluskb.com/scripts/Where_do_I_put_my_answer1186.html
As you can see I need to install solr under the html/WEB-INF directory, but read what it says.. its very confusing:
"All Servlets should be uploaded in the /html/WEB-INF/classes directory. Any unpacked custom classes and resources should be uploaded in the /html/WEB-INF/classes directory, while classes and resources packed in Jar files should be uploaded to /html/WEB-INF/lib."
uhh... so which is it? /classes? or /lib? I dont think they explain that very well and I'm a little confused by this statement. Also what exactly do I install? With a normal solr install, solr is put somewhere else, the war file is copied into tomcat and the rest of solr is referenced using some kind of XML configuration file.
Also, since I'm a little new to Java and servlets, can someone explain the tomcat file structure to me (in great detail will definitely get you a +1 from me) and where things should go and why?
Thanks in advance!
Web application structure is defined by J2EE spec, it's not limited (or specific) to Tomcat per se. Here is a detailed tutorial covering its layout. Briefly, however, it's as follows:
There a base (root, home, whatever you want to call it) folder which serves as root of web application, everything else goes under it.
All public stuff (html, images, CSS, javascript, JSP, what have you) goes under that folder (directly or via subfolders).
There's one special folder, also located directly under root, called WEB-INF. It contains non-public stuff, like application descriptor (web.xml), classes (which go into WEB-INF/classes folder), libraries (WEB-INF/lib) and possibly configuration files.
Application can be deployed either using expanded structure above or as WAR (web archive) which is basically an archive containing everything above starting at root folder level (but not including root).
The distinction between classes and lib folders is simple: all packaged libraries (JAR files) need to go into lib; all unpackaged classes (and resource files that need to be in classpath) have to go into classes preserving their directory structure (e.g. com.mypackage.Blah class should go into classes/com/mypackage/)
In your case, it looks like you can only have one web application deployed and it has to be deployed to /html folder. If you're deploying a war file, you need to extract it to that directory (e.g. from within that /html folder run jar xvf solr.war or whatever it's called).
In our application(applet) I want to enable export functionality if one of the required jars is found. I do not want to add this jar applet references to avoid download size.
I am using Class.forName with one of the classed to check whether particular is available. In local machine Class.forName call retruns an instance although the jar is not in any of the class paths.
Can anybody explain tomcat class discovery mechanism.
Applets run at the client side(inside the browser of the user) not on the Tomcat web server, so this is unrelated to Tomcat.
You'd want to investigate how Applet classloaders work.
Usually they will try to downloading the classes from the web server under the same Url as the applet was fetched from. So if the applet is at http://www.example.com/Hello/HelloApplet
and needs the class foo.bar.MyClass it will try to download http://www.example.com/Hello/foo/bar/MyClass.class if it isn't found locally.
Based on your description of having an Applet I don't see any option but to include the jar file in the applet tag as the applet runs on the client side.
You could set HTTP cache headers for the jar files to allow the client browser to cache them, therefore, you only pay the download cost only once.
For frequently changing jar files include the a version number in the jar file name to avoid client side caching issues with same named but contentually different jars.
Edit: Although the question is about the way tomcat discovers the jars I think the root cause of the problem is elsewhere.
In Tomcat 6 on the server side Tomcat searches the $TOMCAT_HOME/lib and WEB-INF/lib directories for your jar files. If you add or remove files there you usually need to restart the entire Tomcat instance.
Edit2:
Your experience about locating the jar file might be because you run the HTML page from the same directory where your webapp resides or you have the JAR file in a common place or common classpath location (for example in the JRE/lib/ext directory).
I am having a hard time following your question. Are you trying to download classes into an applet if a particular runtime condition is met? From 6u10 I believe you could dynamically download extensions with DownloadService. Going back to 1.2, you can use URLCLassLoader.newInstance, although that wont be so good on the cache side of things.
This question isn't very clear. Tomcat and Applets are completely different in terms of class loading. Applets have a security manager that prevents certain things, such as loading arbitrary classes. They have to download the classes from the web server. The web server doesn't have to be tomcat or even Java; the applet files are just files served over plain HTTP.
As for Tomcat, this article explains version 6's classloading. In particular, Tomcat uses a heirarchy of classloaders to find classes. There are several well-known locations where jars are automatically loaded, such as $CATALINA_HOME/lib or $CATALINA_HOME/shared/lib. It also loads the web-app's own jars and classes. The classloaders work as follows:
The bootstrap class loader looks in the core Java classes folders.
The system class loader looks in the $CATALINA_HOME/bin/bootstrap.jar and
$CATALINA_HOME/bin/tomcat-juli.jar
The WebAppX class loader looks in WEB-INF/classes and then WEB-INF/lib
The common class loader looks in $CATALINA_HOME/lib folder.
The shared class loader looks in $CATALINA_HOME/shared/classes and $CATALINA_HOME/shared/lib if the shared.loader property is set in conf/catalina.properties file.
Reason: One of the other libraries(jars) referenced earlier had the class I was looking for.
I am running several webapps on Jetty 6 through Apache. They are set to hot deploy using .xml files in the contexts/ directory. Those .xml files simply define WebAppContext instances and tell them where to look for a WAR file. `touch'-ing their contexts/.xml files picks up changes to JSPs defined in the relavnt WAR file, which is great.
The problem is that changes to the JARs contained in the WAR file's WEB-INF/lib folder are not picked up. I assume that this is because these JARs are cached somewhere. That assumption is based on the fact that restarting Jetty picks up the changes.
So, the question is: Is it possible to turn off this caching behavior or in some other way get WebAppContext instances to pick up library changes? If so, how?
JBoss hot deploy scanning doesn't check the lib folder:
http://community.jboss.org/wiki/HotDeployLibDirectory
Not sure if Jetty has the same behaviour, but, you could try moving one of your jars into the same folder as one of your jsps to see if this is the case.
If that's not an option then this might help:
http://www.jroller.com/larrywilliams/entry/jetty_hot_deploy
You need to set the scanInterval property to a number larger than zero.
See more here