Adding an external directory to Tomcat classpath

TomcatClasspath

Tomcat Problem Overview


I have a folder in my C: drive as C:\app_config\java_app This folder contains some locale specific property files.

I have a java class (PrjPropertilesLocator) that loads the property files based on default locale on the startup of the web App.My web application is running inside tomcat. The problem is how should i set this directory C:\app_config\java_app in the tomcat classpath so that this becomes available to the ResourceBundle inside the PrjPropertilesLocator class. Is there a way i can set this folder specifically for a Single web app that needs it.I do not want to put the property files inside WEB-INF/classes folder.

On weblogic this runs fine.I set the directory inside the weblogic classpath in one of its startup scripts and it works fine. But on Tomcat i tried putting it in startup.bat also in setclasspath.bat, but was not able to do so successfully.

Tomcat Solutions


Solution 1 - Tomcat

Just specify it in shared.loader or common.loader property of /conf/catalina.properties.

Solution 2 - Tomcat

See also question: https://stackoverflow.com/questions/6345793/can-i-create-a-custom-classpath-on-a-per-application-basis-in-tomcat

Tomcat 7 Context hold Loader element. According to docs deployment descriptor (what in <Context> tag) can be placed in:

  • $CATALINA_BASE/conf/server.xml - bad - require server restarts in order to reread config
  • $CATALINA_BASE/conf/context.xml - bad - shared across all applications
  • $CATALINA_BASE/work/$APP.war:/META-INF/context.xml - bad - require repackaging in order to change config
  • $CATALINA_BASE/work/[enginename]/[hostname]/$APP/META-INF/context.xml - nice, but see last option!!
  • $CATALINA_BASE/webapps/$APP/META-INF/context.xml - nice, but see last option!!
  • $CATALINA_BASE/conf/[enginename]/[hostname]/$APP.xml - best - completely out of application and automatically scanned for changes!!!

Here my config which demonstrate how to use development version of project files out of $CATALINA_BASE hierarchy (note that I place this file into src/test/resources dir and intruct Maven to preprocess ${basedir} placeholders through pom.xml <filtering>true</filtering> so after build in new environment I copy it to $CATALINA_BASE/conf/Catalina/localhost/$APP.xml):

<Context docBase="${basedir}/src/main/webapp"
         reloadable="true">
    <!-- http://tomcat.apache.org/tomcat-7.0-doc/config/context.html -->
    <Resources className="org.apache.naming.resources.VirtualDirContext"
               extraResourcePaths="/WEB-INF/classes=${basedir}/target/classes,/WEB-INF/lib=${basedir}/target/${project.build.finalName}/WEB-INF/lib"/>
    <Loader className="org.apache.catalina.loader.VirtualWebappLoader"
            virtualClasspath="${basedir}/target/classes;${basedir}/target/${project.build.finalName}/WEB-INF/lib"/>
    <JarScanner scanAllDirectories="true"/>

    <!-- Use development version of JS/CSS files. -->
    <Parameter name="min" value="dev"/>
    <Environment name="app.devel.ldap" value="USER" type="java.lang.String" override="true"/>
    <Environment name="app.devel.permitAll" value="true" type="java.lang.String" override="true"/>
</Context>

UPDATE Tomcat 8 change syntax for <Resources> and <Loader> elements, corresponding part now look like:

<Resources>
    <PostResources className="org.apache.catalina.webresources.DirResourceSet"
                   webAppMount="/WEB-INF/classes" base="${basedir}/target/classes" />
    <PostResources className="org.apache.catalina.webresources.DirResourceSet"
                   webAppMount="/WEB-INF/lib" base="${basedir}/target/${project.build.finalName}/WEB-INF/lib" />
</Resources>

Solution 3 - Tomcat

In Tomcat 6, the CLASSPATH in your environment is ignored. In setclasspath.bat you'll see

set CLASSPATH=%JAVA_HOME%\lib\tools.jar

then in catalina.bat, it's used like so

%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% 
-Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" 
-Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" 
-Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%

I don't see any other vars that are included, so I think you're stuck with editing setclasspath.bat and changing how CLASSPATH is built. For Tomcat 6.0.20, this change was on like 74 of setclasspath.bat

set CLASSPATH=C:\app_config\java_app;%JAVA_HOME%\lib\tools.jar

Solution 4 - Tomcat

What I suggest you do is add a META-INF directory with a MANIFEST.MF file in .war file.

Please note that according to servlet spec, it must be a .war file and not .war directory for the META-INF/MANIFEST.MF to be read by container.

Edit the MANIFEST.MF Class-Path property to C:\app_config\java_app:

See Using JAR Files: The Basics (Understanding the Manifest)

Enjoy.

Solution 5 - Tomcat

You can create a new file, setenv.sh (or setenv.bat) inside tomcats bin directory and add following line there

export CLASSPATH=$CLASSPATH:/XX/xx/PATH_TO_DIR

Solution 6 - Tomcat

I might be a bit late for the party but I follow below steps to make it fully configurable using IntelliJ's way of in-IDE app test. I believe the best way to go with is to Combine below with @BelusC's answer.

1. run the application using IDE's tomcat run config. 
2. ps -ef | grep -i tomcat //this will give you a good idea about what the ide doing actually.
3. Copy the -Dcatalina.base parameter value from the command. this is your application specific catalina base. In this folder you can play with catalina.properties, application root path etc.. basically everything you have been doing is doable here too. 

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRajatView Question on Stackoverflow
Solution 1 - TomcatBalusCView Answer on Stackoverflow
Solution 2 - TomcatgavenkoaView Answer on Stackoverflow
Solution 3 - TomcatTrentonView Answer on Stackoverflow
Solution 4 - TomcatKoekieboxView Answer on Stackoverflow
Solution 5 - TomcatSudhir NView Answer on Stackoverflow
Solution 6 - TomcatOlgun KayaView Answer on Stackoverflow