I use Hibernate in an extension-like server-side application, and I put my binaries to the Extensions folder of the server application.
The problem is, that if I run the server, the root folder is the root folder of the server application, and not the root of the binaries. Thus, Hibernate searches the config file in that folder, and it tries to find the classes from that folder. I guess this is related to the JVM, as the server launches it. The config file is not a problem though, because I can just copy my config files there, but all the paths gone invalid.
As a result, in my generated mapping file, I have a class org.gmate.data.SomeClass.java, but it won't find it.
My question: Is there any way, solution or workaround, that I can set the root folder of Hibernate to be the Extension folder, so it starts to get the classes from there?
Thanks for all the replies in advance,
gmate
I finally found the solution for my problem. The problem was not the assumed root folder as I thought, but the Class Loader that the server uses. As it was in my Extensions folder, a CustomClassLoader loaded my classes. and they did not appear in the classpath. As I moved my clsses into a jar file, and added that jar file to the classpath, I managed to use hibernate. Adding the Extension folder to the classpath resulted in loading these classes with SystemClassLoader, but then the advantages of the Custom ClassLoader dissappeared.
Related
In one of our production environment we have a messed up structure,
The tomcat WEB-INF has ../classes with configurations and ../lib with jars.
We find that the classes directory has a directory following the package structure as below,
Sample:
com/test/A.class
Within the lib directory also we have another jar with the same class packaged.
The real issue was looked into when we found that duplicate processing is happening though it is not sure if the issue is because of this.
The actual question is when tomcat starts will two instances of the same class gets created and parallel processing happen? Is it a possibility because both classes directory and lib directory is in the classpath.
It is not about tomcat but classloaders. The hierarchy is BootstrapLoader(rt.jar)->ExtensionClassLoader(java.ext.dir location)->ApplicationClassLoader(from application -classpath parameter).
So, if the class is loader by any loader from higher hierarchy, it will not get loaded again from any other jar.
If you want to load a class from a particular jar without changing the classloading order, please refer to How to load Classes at runtime from a folder or JAR?
I have implemented log4j in my web application project. Project is done using net beans,using tomcat 7.0.41. At first,I created log4j.property file and placed under web page->Web-INF->classes->log4j.properties in net beans and it asks me to locate the file in my project,so I manually located that file to implement log4j in my application. After that I changed the place of the log4j.properties file to myproject->build->web->WEB_INF->classes->log4j.properties in location of my project saved, now its working fine, it did not ask me to manually locate the property file, It takes automatically when my class files executed. Now my problem is that once I committed the project and again checkout the project on some day, property file does not appear and it again ask for property file. So where can I create the log4j property file in my project so that my team mates can utilize it when they checkout project in their system.
Normally you put log4j.properties to src/main/resources/ and it will be copied to the right place by the build process.
I never use net beans, but I think put log4j.properties under Classpath will work.
Not sure how Net Beans handels this, but i think that the "build" directory is where the "compiled" project is put to.
So i would not recommend to put any files there which should be versioned because mostly those directories are ignored for versioning ( see .gitignore files for example when using git).
Resources like property files should be within the sources and your IDE should copy them to the correct place when building the project.
I am trying to deploy a dynamic web project in a way that allows me to dynamically add Quartz jobs to the classpath. Here is my thinking.
'If I read configuration from an XML file containing a fully qualified classpath, then use Class.forName() in the class to create an instance of said class from the config XML, then I should be able to access dynamically added classes placed in Tomcats TOMCAT_HOME/lib directory'.
Before this update, the application worked fine, but I had these newly externalized classes contained in the war. However, I can no longer do this because I:
Don't want to redeploy the war every time a new job is required.
Cannot take the server down to add new jobs as there are jobs that need to run continuously.
However, I am getting a NoClassDefFoundError when I run the class.forName() method. I have already verified in catalina.properties that the lib directory in Tomcat is in the common.loader property.
My question is, how can I get my WAR classes to recognize the classes in a jar in the Tomcat common library. Any ideas? Thanks.
addition:
#BalusC: I have actually already developed a web based admin screen which allows the user to edit the XML config file to add new jobs. However, to add not just another instance of a job, but an entirely new job, there needs to be code definition of this new job. I want that to be placed into a jar file to be dropped into the tomcat lib directory to be picked up by class.forName().
Hopefully, Tomcat does not reload automatically your context or loads the jars in your classloader automatically. It could result in uncontrollable behaviors.
You will never be able to access those new classes in the WebAppClassLoader (the one managed per tomcat context) without loading the explicitly the jar through an URLClassLoader. I'll advice to use an absolute path to the jar. For some dark reasons I had issues with relative path.
If you want to know the tomcat installation path and for instance the lib directory, you could use the catalina.home and catalina.base environment variables.
HIH
I am using hibernate and put xml mapping files in src/hib directory.
but when debug application eclipse run directory is bin.
Is possible to forse Eclipse also copy .xml files of mapping also to bin/hib directory?
Thanks.
Eclipse should do it automatically. The problem is that Hibernate, by default, loads its config file from the default package, and not from the hib package.
Notice that it doesn't load it by opening a file, from the current directory. It loads it as a resource from the classpath. Even if the config file ends up in a jar file, Hibernate will be able to load it, provided it is at the expected location in the package tree (i.e. at the root of the tree).
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.