log4j multiple configuration files - log4j

I have couple of projects embedded in a web app as jars. Each project has a log4j.properties file. When the web app is deloyed, which configuration file gets used and how to override the configurations in log4j.xml in a jar file. The jars are not web projects. They are more like service layer code. What is the order in which the log4j.properties file is loaded in the below scenario
Web-project
classes
log4j.properties
ProjectB.jar
com
log4j.properties
ProjectC.jar
com
log4j.properties and so on.

If your jars are separate web applications, each web application should use the one it first finds on the classpath (WEB-INF/classes).
You can pass a -Dlog4j.configuration=path_to_file setting to e.g. the tomcat startup to make sure that it uses the one you intend it to use.
However, this would then to my understanding and knowledge be the one that tomcat will use for every webapp that is deployed.
Question here is how you deploy your apps. Either all web applications in one tomcat in which case you probably want each web application to use a different log4.properties (or log4j.xml) or in the case where you specify one to tomcat, it should use the one you specify.
What it boils down to as far as i know: Either the first one found on classpath (remember: each web-app has it's own classpath) or the one you specify via the -D setting.
Just found this reference which i think nicely summarizes the main concepts of logging in tomcat and webapps deployed in tomcat: http://wiki.apache.org/tomcat/FAQ/Logging
If you need even more control over the log4j logging, you can resort to coding the log4j configuration in java. However, this would mean that you have to modify the source code and add code into it, which relates to infrastructure and relates deployment details to your application (not so nice).

If you set additivity to false in common packages at ProjectA, ProjectB and WebProject your log will not duplicate.
log4j.additivity.[logged package] = false
For example:
log4j.properies -> Project A, Project B
log4j.additivity.org.spring.framework = false
All org.spring.framework log will come from WebProject ignoring ProjectA and ProjectB.

Related

where is war exploded in Liferay 7 tomcat after getting copied in osgi folder

I deployed a portlet in liferay 7 and it got deployed successfully and was available for use. I want to replace the jsp file, in earlier version I could see my application in tomcat/webapps folder and replace it quickly.
Now I am unable to locate the exploded war in liferay 7. I can only see the war in osgi/war folder.
Can someone help me with that.
Thanks in advance.
While I mostly agree with what Olaf wrote, I do understand the need to be able to make changes in JSP files and try them quickly during development. I'm afraid I don't have the solution for that yet.
However, let me answer the question you asked:
where is war exploded in Liferay 7 tomcat after getting copied in osgi folder
It is NOT (at least not the way it was done by application servers)! When you deploy a WAR file in Liferay 7, it will automatically (on the fly) convert it into OSGi bundle and install it in OSGi runtime. This way now Liferay is fully in charge of deploying plugins and does not need to rely on various application servers.
PLEASE NOTE: Every bundle has it's own state folder. In Liferay those are in <LIFERAY_HOME>/osgi/state. If you know the bundle ID you can easily find it. It may be (I haven't checked) that you'll find some JSP files there. The reason I'm writing this is to warn you (in case you figured it yourself) to NEVER modify bundle's state folder manually. Doing so may brake the whole environment. In worse case scenario you may have to redeploy everything in clean environment.
You should not rely on behavior like this. In previous versions it was the task of the application server to compile changed JSPs at runtime. However, this is bad practice in production systems and totally screws up your maintainability. If you need to update some UI code frequently, I'm suggesting you change your implementation to utilize ADT (Application Display Templates), e.g. through Freemarker or Velocity. Those are meant to be updated at runtime, where the JSP updates were a side effect of Tomcat's default (development friendly, production hostile) configuration

how to define multiple log4j configs with Jetty server in web.xml

Here's what I want to do:
- being able to have separated log4j.properties for each different deployment "war"
- being able to define in ant build, or web.xml, using system parameter on which log properties to use.
My project setup is Jetty with Jersey as REST API, without Spring.
I've done some research and it turns there are other Spring solutions to set in webl.xml but I'm not using spring.
I also know Jetty is using slf4j but if switching to slf4j, would I be able to do this more easily?
What would be a best way to solve this, so that in web.xml or ant build, log4j config can be customized defined?
Thanks a lot!
EDIT:
I figured that I can start another servlet with some init-param defined. Then on a separated HttpServlet implementation to set the PropertyConfigurator.configure([name of the log4j config]);
Is this adding one more servlet an ideally way of handling this?
Lots of different ways to handle this.
Since your mission is not different logging per Servlet, or per Webapp...I wouldn't solve the problem in the servlet or webapp locations but at the server level. To me, you want to log all this information to the correct place, not just all the information once the servlet has been deployed. To this end, I would enable the slf4j-api support in jetty and then look into the best way to handle that from the slf4j side of things. With that you can use whatever logging framework you want, slf4j-simple, log4j or logback..whatever you like.
Alternatively, if you really want to avoid the server side of logging, I supposed you could just use a log4j.properties file in the resources directory and then on jetty startup on the command line serve out a different resources directory. Figure out what options you want and startup with:
java -jar start.jar OPTIONS=Server,jmx,jsp,resources-[dev,qa,prod]
cheers

Liferay - Share Utils class between 2 different portlets

I'm developing a Liferay application, consisting on 2 different portlets, an both have to make certain operations in common, so I decided to put that operations in static methods in an external Utils class.
I have to externalize that class to avoid duplicating the same code in both portlets, and I want to have the portlets in different WAR files.
I know I can package the Utils class in a JAR file, but we are still developing and we don't want to regenerate the JAR and restart the Tomcat for every change.
Which is the best option and how can I perform it?
If you're using the Liferay SDK, you can use the clients (recently changed to shared) directory to put your common code.
A good example is how deploy-listener-shared is used in conjunction with deploy-listener-hook.
From what it looks like, all the configuration you need to do is to modify your build.xml files that will use the client\shared classes. If you look at build file of deploy-listener-hook you can see all you need to add is the.
For the new SDK:
<property name="import.shared" value="my-utils-shared" />
For the older SDK:
<property name="dependent.clients" value="my-utils-client" />
Hope this helps!
There is another method that involves building a JAR file but it doesn't require a server restart (on Tomcat at least).
Write a build script for your JAR file so it compiles, builds the JAR and finally copies it to the following location:
{tomcat}/webapps/ROOT/WEB-INF/lib
Then in your portlet open the "liferay-plugin-package.properties" (in Liferay Developer Studio / Liferay IDE this should open with a nice GUI).
Then add the name of your JAR to the "portal-dependency-jars" list in this file so in the source it would like (Or just hit the "Add" button in the GUI and select the JARs you want):
portal-dependency-jars=my-custom-lib.jar,my-other-custom-lib.jar
Save the file, and redeploy the portlet, and the JAR will be copied across when the portlet is deployed.
I've used this method for custom JARs, and 3rd party JARs that I've needed to use in my portlets.
For the development phase just package the jar file with both applications.
Unless one application depends on the other somehow it is completely ok.
Another solution is to use JRebel tool. It will allow you to redeploy jar in tomcat without restarting.
Also you may have several portlets in one .war. You may just define them both in portlet.xml.

jboss7 + same log4j configuration for different apps

I want to deploy some different applications using one jboss (jboss as 7). Can anyone make it clear for me if its possible to set one log4j configuration (log4j.xml) for multiple wars and ears or i'll have to put a copy of configuration into each archive?
Or maybe someone can suggest a differeng logging engine, more native to jboss7?
log4j configuration is always global to runtime. ie. A JBoss instance can't have multiple log4j configuration. log4j can be initialized or reinitialized with a single config file. it can be a simple properties file or a XML incompliance with log4j.dtd packaged with log4j*.jar. start the jboss instance with -Dlog4j.configuration=/anypath/log4jconfig.xml
I do not believe there is a way to configure log4j globally. JBoss AS7 uses JBoss Logging for it's log provider. You can configure the logging subsystem is in the standalone.xml or the domain.xml depending on if you're running in standalone or domain mode.
The documentation is not greatest unfortunately, but if you install the jboss-as-logging_1_1.xsd in your IDE you can get auto-complete. All the schemas are located in the docs/schema under the installed directory.

Using log4net in a complex software

I'm using log4net logging in my software that consists of several applications.
I want to have one common library for this.
I created a library and put it in the conficuration file. In AssemblyInfo.cs placed attribute:
log4net.Config.XmlConfigurator(ConfigFile = #"c:\logging.xml", Watch = true)
It work for windows service, but in dosn't work for asp.net application.
It work in asp.net if delete attribute from common library and put in into global.asax. However, this leads to that section of the log4net configuration must be made in the windows service.
There is also a business process which causes our library through the
remouting. I want the logging was carried out there too.
Is there way around this?
In my opinion the library should not define where the configuration file is found. Maybe a better idea would be to have a helper method that allows you to configure log4net quickly; that method would take an optional parameter for the config file path and would try to load the configuration file from the specified path first and if that does not work fallback to some maybe the current folder, the application folder or even the web / app.config.
If you insist that it must be an absolute path then you need to give the IIS Application Pool user read access to this file. This way the configuration by attribute should work for services and ASP.Net applications. I do not understand what you mean by "remounting".

Resources