I am trying to create an environment where the application build remains same across environments. To support this I've externalized any property files to be read from an external directory e.g.$CATALINA_BASE/conf/app1/config
We use ehcache for caching (for CAS) and for replication between instances I seem to get the errror if the ehcache-replicated.xml is not present in the WEB-INF/classes directory. I've tried updating the setenv.sh of Tomcat so:
CLASSPATH=$CATALINA_BASE/conf/app1/config/ehcache-replicated.xml
export CLASSPATH
I also tried adding to JAVA_ENDORSED_DIRS but none of them seem to work. Any ideas?
A classpath entry is a directory, not a file. So try CLASSPATH=$CATALINA_BASE/conf/app1/config, it might work.
I am saying might because Tomcat is applying class loader isolation. A war won't see the classpath of the application server. So, it depends where you are setting the classpath.
In general, adding the classpath entry in catalina.properties shared.loader works. But that's from the top of my head.
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.
Using spring boot, deploying on ubuntu tomcat with war
in application.properties,
logging.path = classpath:/log
does not work on local machine or deployed at all. I did check my target/classes/log folder too.
it used to work with
logging.path = src/log
spring.log would be generated.
what am I doing wrong?
logging.path needs to be a directory, not a classpath.
This should work:
logging.path = /log
See this part of the docs for all the legal combinations:
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html#boot-features-logging-file-output
You probably shouldn't be trying to log to your classpath in the first place. And it likely doesn't make sense in the context of a deployed application. If you imagine an application packaged as a self-contained executable JAR, your classpath essentially becomes your JRE folder + your JAR. How would you be able to write to a file inside the JAR?
Best bet is to choose a folder somewhere on your file system and log to that. I usually use the same location where I put my JAR file, or use a /var/log/... folder to log to. If it is something only temporary, then I would log it to /tmp, but be careful with that as /tmp can sometimes have cleanup jobs that conflict with your logging settings.
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 weblogic 10.3.4, I am trying to write log with log4j. but at runtime my application is not getting any log4j.properties. even this is not generating any warning as "initialization of log4j has error".
I have tried my properties file to put in src folder, classes folder and then I created one jar and put it in domain lib. still its not picking. even when I am writing log with same jar in standalone application, its working fine.
please help me with valuable suggestions.
I tried the solution proposed at Oracle forums.
Excerpt from that link at Oracle forums:
I've only modified the scritp startWebLogic.cmd:
set LOG4J_CONFIG_FILE=log4j.xml
set SAVE_JAVA_OPTIONS=%JAVA_OPTIONS% -Dlog4j.configuration=%LOG4J_CONFIG_FILE%
#REM set SAVE_CLASSPATH=%CLASSPATH%
set SAVE_CLASSPATH=%CLASSPATH%;C:\Oracle\Middleware\user_projects\domains\domain\config
In this way I've put all the config folder inside the classpath, and I can use it in future to hold other libraries configuration files (for example oracle coherence config).
I tried this approach on a different properties file as well and that worked well!
You need to either specify where the application should find its log4j.properties, or put it onto the classpath of the application. Where the classpath is varies, but in general WEB-INF/classes should work. Other options depend upon how you're deploying the application.
A better long term strategy is to configure your system so that you can change the log4j.properties depending upon the environment. When you're in production, you won't want all of the debug information to appear. Look at the answer to this question or this question for more ideas. One strategy is to define a variable on the command line which gets picked up and defines a directory which contains your configuration files. This works for Tomcat, but there may be other, better, strategies for Weblogic.
It is not a good idea to change the configuration of your server, in particular, don't replace the log4j.jar or log4j.properties in your server directories. The server will depend upon the version that it was designed to use, which may or may not be the same as your version. You can do everything you need to do by changing the war that you're deploying.
I have used this code:
ClassLoader cl = this.getClass().getClassLoader();
URL log4jCfg = cl.getResource(configFile);
if (log4jCfg != null) {
DOMConfigurator.configure(log4jCfg);
}
log.info("log4j is now working on Web App.");
In my case, we used XML configuration:
log4jCfg = "mylog4j.xml";
In WebLogic, we were able to place such file (mylog4j.xml), equivalent to your log4j.properties file, at WebLogic's domain path (specific to the domain were we deploy). This means that domain folder belongs to your application's path. I just tested it with Web applications, I'm not sure if with SOA or EJB projects it works the same way.
When you deploy any application on any server that application should use servers log4j jar.
So if you have added any log4j jar in your application jar/tar/ear, remove it and copy log4j.properties file in the conf folder of the server from where server is picking its configuration files. Or just copy your log4j property content in servers log4j property file.
I'm using internationalization with Spring, and the properties file needs to be on the classpath. I also have some XML files that will need to be on the classpath. Is it acceptable to just include those resources inside the "src" in a sub-directory, and then let them build to the classpath, or is it better to add a different folder to the classpath during startup? I'm using Ant, but from the looks of it this was the approach Maven took (everything under src or test). I'm looking for the most widely accepted industry standards or better alternatives. Thanks!
Is it acceptable to just include those resources inside the "src" in a sub-directory, and then let them build to the classpath
Depends on the sole purpose of the resource in question. With this approach, any minor edit in such a resource file would thus require a full rebuild, redeploy and restart.
This may not necessarily harm for one-time-read startup and applicationwide configuration files like web.xml and application.xml and consorts since that would usually affect (or be affected by) changes in Java source code which require a full rebuild/redeploy/etc anyway.
But in case of runtime files like i18n properties files and environment-specific configuration files (which would/could be managed by a non-developer like a serveradmin or a customer), it is not useful to package it inside the webapplication. This requires knowledge how to rebuild the webapp after edits. You would rather like to externalize it so that only a webapp restart is required to reflect the changes in the configuration, or maybe even not at all, like for ResourceBundle which will just reload automagically.
I myself usually put such files in a fixed path along the servletcontainer and add that path to the servletcontainer's runtime classpath. In case of for example Tomcat, it's configureable as shared.loader property in /conf/catalina.properties. E.g.
shared.loader=/var/webapp
Anything in this folder is then taken in the servletcontainer's (and webapp's) runtime classpath.
Anything you put in your WEB-INF/classes directory is automatically in the CLASSPATH.
I usually put only .java files under /src and /test directories. Any resources that I put elsewhere have to end up in WEB-INF/classes. It's either my IDE (IntelliJ) or Ant that put them there when the WAR file is created.
I would recommend following the Spring examples and put resources where they do.
For example, if you use Velocity as your templating engine, you'll see that Spring configuration allows you to put them under /WEB-INF/vm_views.
Properties are put in WEB-INF/classes.
Check the Spring docs for examples.