Load logback.xml from Manifest Class-path - java

I'm trying to load logback.xml file from outside of my executable myapp.jar file.
The myapp.jar has a META-INF/MANIFEST.MF file roughly like this:
Manifest-Version: 1.0
Class-Path: logger-config lib/lib/jcl-over-slf4j-1.7.18.jar lib/slf4j-api-1.7.18.jar
Main-Class: com.mycompany.MyAppMain
and resides in
my-app/
lib/
jcl-over-slf4j-1.7.18.jar
slf4j-api-1.7.18.jar
logger-config/
logback.xml
myapp.jar
(there is a lot of other jar dependencies, cut those out).
Now, if I run the application using java -jar myapp.jar, it starts OK, but it does not pick up the logback.xml file.
From their docs:
If no such file is found, it checks for the file logback.xml in the classpath..
( http://logback.qos.ch/manual/configuration.html )
I know I can override this using logback.configurationFile, but is there a way to just put the XML file to classpath so that logback loads it automatically? It seems to work only if I package the logback.xml to myapp.jar (placing it in src/main/resources dir), but then the config file will be propagated to other JARs that uses myapp.jar as a dependency.

Maybe you just cut it out, but your classpath does not specify the logback-classic dependency.
You will have to make sure logback appears before slf4j in your class-path definition. Also, note the trailing slash for the logger-config path - logback will not find your logback.xml without it (see here for details).
Something like this should work:
Class-Path: lib/logback-classic-1.1.6.jar lib/logback-core-1.1.6.jar lib/jcl-over-slf4j-1.7.18.jar lib/slf4j-api-1.7.18.jar logger-config/

Related

EJB SLF4J with log4j - No appenders could be found

I'm trying to use SLF4J with log4j in a Bean inside a EJB, I have already tried to place the log4j.properties file in quite a few places but I keep getting this error in the Glassfish Server console:
Grave: log4j:WARN No appenders could be found for logger (uy.ort.enviosya.cadets.services.CadetsBean).
Grave: log4j:WARN Please initialize the log4j system properly.
Grave: log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info
This is my properties file:
# LOG4J configuration
log4j.rootLogger=DEBUG, Appender1,Appender2
log4j.appender.Appender1=org.apache.log4j.ConsoleAppender
log4j.appender.Appender1.layout=org.apache.log4j.PatternLayout
log4j.appender.Appender1.layout.ConversionPattern=%-7p %d [%t] %c %x - %m%n
log4j.appender.Appender2=org.apache.log4j.FileAppender
log4j.appender.Appender2.File=C:/Users/Log4jWebDemo.log
log4j.appender.Appender2.layout=org.apache.log4j.PatternLayout
log4j.appender.Appender2.layout.ConversionPattern=%-7p %d [%t] %c %x - %m%n
The questions related to this problem say I should place it in the classpath but honestly I don't know what they mean by that (totally new to EJB).
This is what I'm doing in the bean:
#Stateless
public class SomeBean implements SomeBeanRemote {
private static final Logger LOGGER = LoggerFactory.getLogger(SomeBean.class);
#Override
public someMethod() {
LOGGER.info("Prueba");
...
}
...
}
Plus, should I be placing the file inside the EJB? What if I want to modify the destination of the Appender2 then?
I'm using Netbeans 8.2.
Update 1
I have placed it inside the META-INF folder of my ejb, and from what I can see it is present in that same folder in the Cadets-ejb.jar that I'm deploying inside .ear.
But I'm still getting the same error.
Partial folder structure:
Some
build
Some-ejb
build
dist
nbproject
src
conf
META-INF
java
test
dist
lib
nbproject
src
Update 2
I managed to get it working but by placing the properties file by hand in the correct place in the build folder, which means I need to do this every time I do a clean-build.
I tried placing it in the src folder but when I build it doesn't get copied, only what is inside src/confgets copied and that is the wrong location for this file.
Why is the file in src being ignored on build?
This is my structure now:
Some
/build
/Some-ejb
/build
/dist
/nbproject
/src
/conf
/META-INF
MANIFEST.MF
/java
/log4j.properties
/test
/dist
/lib
/log4j.jar
/nbproject
/src
I now that the file, once the jar is created needs no be at the same level that META-INFand my class packages.
Solution
I solved it by placing it here
Some
/build
/Some-ejb
/build
/dist
/nbproject
/src
/conf
/META-INF
MANIFEST.MF
/java
log4j.properties
/test
/dist
/lib
/log4j.jar
/nbproject
/src
After I googled a lot, i think i found a solution for this:
FOR A GLOBAL CONFIGURATION
If your log4j library is included within your EAR file, then check your app server's JVM properties to ensure the log4j.configuration property is set:
Login to the Glassfish Admin Console (http://[hostname]:4848/)
Click on 'Server(Admin Server)'-> Click on 'server-config' Configuration -> JVM Settings -> JVM Options. (depends of your server version, but the important is JVM Settings > JVM Options)
If an entry for -Dlog4j.configuration exists, verify that it contains the location of your log4j.properties file
If an entry do not exist for -Dlog4j.configuration, create one. It must follow the following template: -Dlog4j.configuration=file:///path/to/your/log4j.properties
Restart the GlassFish.
Deploy sample app and check if the Log4J statements are now available.
In case your project doesn't contain log4j library
Copy log4j.jar inside the GLASSFISH_HOME/lib.
FOR A PROJECT
For instance, you can have the following structure:
Some
/build
/Some-ejb
/build
/dist
/nbproject
/src
/conf
/META-INF
MANIFEST.MF
/java
/test
/dist
/lib
/log4j.jar
/nbproject
/src
/log4j.properties
In order to include the log4j-files into your classpath, you have to put the following into the META-INF/MANIFEST.MF on your EJB Project:
Class-Path: src lib/log4j.jar
Yes: it’s relative to the EAR, not to the EJB Project.
Do not put the log4j.properties itself in the classpath, only the directory that contains that file.

Where to place config files in JARs?

My JAR currently has the following structure:
myapp.jar
META-INF
MANIFEST.MF
net
myapp
MyAppDriver.class (fully qualified as net.myapp.MyAppDriver)
<lots of other classes>
My app requires the need to read a file from the runtime classpath, and configure itself based on the contents of the file (simplelogger.properties from the SLF4J framework).
Where do I place simplelogger.properties in the JAR? Do I need to set anything inside MANFIEST.MF as well?
Thanks in advance!
You can place the file in any JAR anywhere you would like. If you want it to live alongside MyAppDriver.class, for example, you could then call getClassLoader().getResourceAsStream("net/myapp/simplelogger.properties") to get an InputStream to that file. You don't need a manifest for this to work.

Read specific resource from classpath

I have a maven project and in class-path (resources folder according to maven standard layout) I have several log4j.xml files, like this:
-resources
-log4j.xml
-folder1
-log4j.xml
-folder2
-log4j.xml
How I can read log4j.xml located at root? I think the following code doesn't guarantee that I will get log4j.xml from root:
Thread.currentThread().getContextClassLoader().getResourceAsStream("log4j.xml")
Unless some other jar file is in the classpath of the current thread(s classloader, before yours, and also contains a log4j.xml file at the root, your code will do what you expect it to do.
To get the other one you would use "folder1/log4j.xml" as path.

log4j.properties, where to put it

According to log4j manual, I should put log4j.properties to the src folder. I copied this file to all the possible places I think it will affect log4j. However, this does not work.
TestEM class contains many unit test functions (I use testng). I run one of these test functions which references a class in the feedback.strategy package.
Here is the content of the log4j.properties file:
#log for class1
log4j.category.Demo1=DEBUG, dest1
log4j.appender.dest1=org.apache.log4j.FileAppender
log4j.appender.dest1.File=C:/Users/Asus/workspace/FeedbackProcess/logs/class1.log
log4j.appender.dest1.layout = org.apache.log4j.PatternLayout
log4j.appender.dest1.layout.ConversionPattern= %d %p [%t] (%c) \u2013 %m%n
This is mostly a question of convention and/or personal preference. What I am accustomed to is to create another source directory (e.g. config or resources) in the project root (next to src and test), then place the log4j.properties there. This can by done by you right-clicking on the newly created folder and choosing Build Path -> Use as Source Folder. Optionally you can specify some inclusion/exclusion patterns too.
Log4j looks for the properties file on the root of the classpath by default. With the above setup the properties file gets copied to the output directory and it will be on the root of your classpath during development.
Later during the deployment the log4j.properties would get bundled in the jar/war file too. You might want to override the bundled properties by specifying an alternative config folder on the classpath during runtime. (see this other question and the docs about the order entries take precedence on the classpath)
You need to put the log4j.properties file on the application classpath.
maybe the file log4j.properties is being read correctly and the problem is with the configuration in log4j.properties file. Does adding this line to the begining of log4j.properties make any difference (assuming that you are have some logging statements in your class files)
log4j.rootLogger=DEBUG, dest1
Place log4j.properties in WEB-INF\classes of the project .
Put log4j-xx.jar under WEB-INF\lib see here for details

Loading context from within a Jar

I need some clarification; I have a jar that I built and inside of the jar it has a custom application-context.xml file that I need to load. I load the file within a class inside of the jar. When I am setting the url of this application-context.xml, is the directory specific to my jar's classpath, or still the project that is using the jar-'s classpath?
For example --
Jar's classpath:
src > main > META-INF > application-custom-context.xml
Project's classpath:
src > Libraries > myjar.jar > src > main > META-INF > application-custom-context.xml
I know these url's aren't accurate :P -- But, inside of my context creation, which directory structure would I follow. This is all theoretical. Somebody asked me this today, and I have no clue how to answer it. I would think that if you call a class from a jar, the classpath should be relative to the contents of that jar.. But, what I think is far from always right :)
The "path" to the Spring context is relative to the classpath. If the jar is included in your classpath (it's in web-inf/lib for example), then it would be treated just as if it was in your project (web-inf/classes).
In other words, if your context file is in "META-INF\spring\context.xml" inside your jar file, anyone who includes your jar file can reference it in the same manner.

Categories

Resources