Log4J Event Viewer Problem - java

I am develloping 2 applications and publishing them on Websphere Aplication Server.
Since I need to write errors that occur on both applications on the event viewer I put the log4j JAR file on the lib folder of Websphere Aplication Server and the file os being loaded successfully.
I have also created the log4j.properties file under src root package of both applications with different variable names and source designation ("Application A" and "Application B").
When an execption is caught it is being logged to the Event Viewer for both cases.
The problem is that the source name presented is the same "Application A" even if the error occured on Application B...
Can anyone help?
Thanks

I'm not sure what you mean by "applications with different variable names and source designation" — that you use differently named loggers in both applications and direct output to different appenders?
Still, I see one problem with your configuration: when you put your log4j jar into WAS lib folder, it's loaded with the class loader common for both your applications (a bootstrap class loader or extension class loader, depending where this "lib" directory is) — and that means log4j is loaded only ONCE. Considering how log4j is initialized (with a static code section), it is also initialized ONCE, meaning that at most one log4j.properties is read.
Try removing log4j from the WAS lib directory and deploy it with every application, see where it gets you.

Related

where should I locate a common ESAPI.properties file used by multiple wars inside an ear?

I have two modules that will use ESAPI with the same properties files (ESAPI and validation.properties).
These modules output to wars that are contained in an ear.
I have the properties files inside one of the war files, where they are found at server start. The other war file seems to work fine and does not complain that it can't find the properties files in the log.
I am using ESAPI to sanitize html and url parameters - I wonder if I even need these property files to be accessible to the second module, or either one since there is no configuration and everything is being done with defaults.
First, let me describe how ESAPI 2.x goes about finding its ESAPI.properties file.
The reference implementation class for ESAPI's SecurityConfiguration interface is
org.owasp.esapi.reference.DefaultSecurityConfiguration
With this default implementation, resources like ESAPI.properties and
Validation.properties can be put in several locations, which are searched in the following order:
1) Inside a directory set with a call to SecurityConfiguration.setResourceDirectory(). E.g.,
ESAPI.securityConfiguration().setResourceDirectory("C:\myApp\resources");
Of course, if you use this technique, it must be done before any other ESAPI calls are made that use ESAPI.properties (which are most of them).
2) Inside the directory defined by the System property "org.owasp.esapi.resources". You can set this on the java command line as follows (for example):
java -Dorg.owasp.esapi.resources="C:\temp\resources" ...
You may have to add this to the start-up script that starts your web server. For example, for Tomcat, in the "catalina" script that starts Tomcat, you can set the JAVA_OPTS variable to the '-D' string above.
3) Inside the
System.getProperty( "user.home" ) + "/.esapi"
directory (supported for backward compatibility) or inside the
System.getProperty( "user.home" ) + "/esapi"
4) The first ".esapi" or "esapi" directory encountered on the classpath. Note this may be complicated by the fact that Java uses multiple class loaders and if you are have multiple applications in a given application server, they may be using different classpaths. For this reason, this option is not generally recommended, but is offered for reasons of backward compatibility with earlier ESAPI 1.4.x versions.
Once ESAPI finds a valid property file (e.g., ESAPI.properties) that it can read, it stops searching for others.
Now, that said, if you want to share a single ESAPI.properties file across all of your .war files, I would recommend going with option #2 and set the System property "org.owasp.esapi.resources" to some common secured directory that both of them can access. Also, you should use a full path name.
The answer was to place the esapi directory containing the properties files in
src/main/application
in one of the modules. This path puts it's contents at the root of the ear.
I'm running ESAPI on a maven project with java 1.8.0_71. I've put ESAPI.properties and validation.properties in
src/main/resources
This worked for me:
Attempting to load ESAPI.properties via the classpath.
SUCCESSFULLY LOADED ESAPI.properties via the CLASSPATH from '/ (root)' using current thread context class loader!
Attempting to load validation.properties via the classpath.
SUCCESSFULLY LOADED validation.properties via the CLASSPATH from '/ (root)' using current thread context class loader!

No log statement is printing using websphere 8.0

I have one application running in WAS8.
we have a jar - commons-logging-1.1.1.jar in WEB-INF/lib
we have one properties file - commons-logging.properties
the content of the file is
priority=1
org.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.LogFactoryImpl
we have org.apache.commons.logging.LogFactory file in WebContent/META-INF/services
the content of the file is
org.apache.commons.logging.impl.Log4jFactory
The log files are created but nothing is written in it. It is not showing any error in the log files in log of appserver.
Please let me know if I am missing something.
Please note: if I keep commons-logging.properties in /opt/IBM/WebSphere/80/AppServer/profiles/AppSrv01/properties, then it works perfectly fine. It is writing in the log files. But as I heard it is not standard practice so I can't keep the file in that place. I have to find some alternative way.
Please help me.
If it is not a requirement to have separate log files for your web application, you can simply remove the commons-log jar and properties from your module (war) and your log statements will write to SystemOut.log according to the log level settings in the WebSphere console (which can be changed at runtime, by the way).
If you must separate application logging, you can refer to this infocenter article that lays out the combination of commons-log jar location, commons-log properties values, and application classloader settings (Parent-First, Parent-Last, commons-log.jar bundled or not, etc) to achieve the desired results.

Webserver deployment issue

My current project is writing a HTTP-Webserver in Java. The server checks a "deployment-directory" every two seconds and searches for a file named content.jar. If the file was changed the server deployes it. The file contains servlets which will be loaded by an URLClassLoader. On every deployment a new classloader is created.
In a different project my servlets are being developed. I wrote an Ant-buildfile that creates the content.jar file and moves it into the server's deployment directory. Unfortunately I get an Ant error:
BUILD FAILED [path]\WebServerServlet\Ant\Build.xml:15: Unable to
remove existing file [path]\WebServer\web\content.jar
I suppose that the file is locked on the filesystem by the JVM - is there a way to tell Ant it should not try to delete and move the file but to overwrite it instead?
Otherwise, does anyone have an idea how to avoid the file getting locked by the JVM by changing my deployment system?
EDIT
I have now found a solution!
As discussed in this question the only thing i had to add was
URLClassLoader loader = new URLClassLoader(..);
//class loading stuff here
loader.close() //the line all the trouble was about
With this appendix my Ant-buildfile is able to delete the "old" jar in the deployment-directory and move the new one into it.
I suspect that the classloader has a lock on the jar. Either way until the lock is released you're not going to be able to move, delete or modify it.
The solution is to write your own classloader. It's this custom classloader that should be monitoring your jar for changes, not the server, then reloading the classes accordingly.
There's a lot involved in writing a classloader to do dynamic reloading - fortunately, it's explained here.

tomcat shared lib - (config) files context rules

Within Tomcat 6's lib (${catalina.home}/lib/) folder I have several shared JAR files such as Hibernate's.
When I debug my web app the console gets LOTs of output by Hibernate, unless I put logback.xml in ${catalina.home}/lib/.
Here's the question's highlight:
If I move that same logback.xml to my web app's /WEB-INF/lib/ folder it is ignored as if there is no file - I get all the output.
That's obviously related to context (on the Java level I presume), but I can't find info about it.
Please help me understand it better, the fundamentals.
Thank you!
I bet it isn't related with the context but rather the classpath hierarchy. Java infrastructure provides a mechanism (ClassLoader) to build classpath hierarchies and Tomcat (as many other servlet containers/application servers) use that to isolate the different JARs/class folders being used in a specific application.
The root class loader is the one that has less visibility inside the hierarchy, nested class loaders can look for a class inside their scope or ask a parent class loader for it if not found. Some application servers allow to configure the class loaders to ask first the parent and then look inside their own scope if the parent can't locate it. However, a parent class loader can't never load a class from a nested class loader.
NOTE: same happens with normal files, as with your logback.xml.
So, you have some hibernate libraries deployed in your Tomcat's lib folder, which is handled by the root class loader in the hierarchy. When you have your logback.xml file in that folder it actually is at the same classpath hierarchy level than your Hibernate JARs, so Hibernate (or the log mechanism being used by it) can load the file because it's within its scope.
In the other hand, the libraries used by your application (WEB-INF/lib) are handled by a different class loader which actually is nested to the previous mentioned one. When you move your logback.xml to your application's library folders you are actually moving it to a wider scope but, since Hibernate has been loaded by a parent class loader, it can not locate the file within its scope (remember, a parent class loader can't load classes or files from its children, just the children can ask the parent for those).

tomcat, 2 webapps, 2 log4js, but both apps log to one file

To elaborate on that, I have a Tomcat server version 7.0.27 running Java 1.6.0_27.
I have two wars, each with their own log4j jar, also using slf4j with slf4j-log4j. Each war has it's own configuration file (log4j.xml).
war 1 should use file log-1.log and war 2 should use file log-2.log but both are logging into log-1.log.
I've checked there are no other log4j jars in the tomcat installation so I'm not sure where the problem is. I've also turned off shared class loading but that made no difference. My next step is to turn on verbose class loader logging and/or start debugging log4j but maybe someone here knows why this is and can save me some time. Thanks for any input on this.
Update:
Ok think I got this one. The log4j xml files are fine. After doing a verbose:class I can see that log4j.jar is only getting loaded once and from neither web application.
I'm working with Documentum. They have a runtime jar required to use their libraries that is an empty jar with a manifest file. The manifest points to a bunch of jars. In other words, they don't use maven... Anyway ... one of those jars happens to be logj4 found in the Documentum installation. So it seems both webapps are using that one. I think this is the problem. To be confirmed...
If you are placing Documentum's runtime jar on your top-level classpath, and that runtime jar is referencing log4j.jar, then it will only load once. You don't have to use that runtime jar, though, or you can use it in just your Documentum .war, if one is non-Documentum.
You didn't post your properties file but i can think of some reasons:
You don't have an appender that writes to the different files, i.e you need appender1 to write to log1.log and appender2 writing to log2.txt
You have the appenders set up right but both the applications are using the same logger, so they both write to the same file.
You have 2 loggers, each with its own appender, but in your code you are not initializing the correct logger:
//there is no logger called com.sample, so it defaults to root logger that has appender that writes to log1.txt
Logger logger = Logger.getLogger(com.sample.MyClass.class);
If you post your properties file and your logger init code it'll be easier to help you.

Categories