How to suppress SLF4J Warning about multiple bindings? - maven

My java project has dependencies with different SLF4J versions. How do I suppress the annoying warnings?
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:xyz234/lib/slf4j-
log4j12-1.5.8.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:xyz123/.m2/repository/org/slf4j/slf4j-log4j12
/1.6.0/slf4j-log4j12-1.6.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
P.S.: This is not the same question as slf4j warning about the same binding being duplicate, the answer there is how to get rid of a false alarm warning, in my case it is a true warning however.
P.S.S.: Sorry, I forgot to mention: I use Maven and SLF4J is included in the dependencies of my dependencies.

Remove one of the slf4j-log4j12-1.5.8.jar or slf4j-log4j12-1.6.0.jar from the classpath. Your project should not depend on different versions of SLF4J. I suggest you to use just the 1.6.0.
If you're using Maven, you can exclude transitive dependencies. Here is an example:
<dependency>
<groupId>com.sun.xml.stream</groupId>
<artifactId>sjsxp</artifactId>
<version>1.0.1</version>
<exclusions>
<exclusion>
<groupId>javax.xml.stream</groupId>
<artifactId>stax-api</artifactId>
</exclusion>
</exclusions>
</dependency>
With the current slf4j-api implementation it is not possible to remove these warnings. The org.slf4j.LoggerFactory class prints the messages:
...
if (implementationSet.size() > 1) {
Util.report("Class path contains multiple SLF4J bindings.");
Iterator iterator = implementationSet.iterator();
while(iterator.hasNext()) {
URL path = (URL) iterator.next();
Util.report("Found binding in [" + path + "]");
}
Util.report("See " + MULTIPLE_BINDINGS_URL + " for an explanation.");
}
...
The Util class is the following:
public class Util {
static final public void report(String msg, Throwable t) {
System.err.println(msg);
System.err.println("Reported exception:");
t.printStackTrace();
}
...
The report method writes directly to System.err. A workaround could be to replace the System.err with System.setErr() before the first LoggerFactory.getLogger() call but you could lose other important messages if you do that.
Of course you can download the source and remove these Util.report calls and use your modified slf4j-api in your project.

PrintStream filterOut = new PrintStream(System.err) {
public void println(String l) {
if (! l.startsWith("SLF4J")) {
super.println(l);
}
}
};
System.setErr(filterOut);
et voilĂ !

Have you read the URL referenced by the warning?
SLF4J: See [http://www.slf4j.org/codes.html#multiple_bindings][1] for an explanation.
Here is what the link states:
SLF4J API is desinged to bind with one and only one underlying logging
framework at a time. If more than one binding is present on the class
path, SLF4J will emit a warning, listing the location of those
bindings. When this happens, select the one and only one binding you
wish to use, and remove the other bindings.
For example, if you have both slf4j-simple-1.6.2.jar and
slf4j-nop-1.6.2.jar on the class path and you wish to use the nop
(no-operation) binding, then remove slf4j-simple-1.6.2.jar from the
class path.
Note that the warning emitted by SLF4J is just that, a warning. SLF4J
will still bind with the first framework it finds on the class path.

If using maven always use the command
mvn dependency:tree
This will list all the dependencies added to the project including dependencies to the jars we have included. Here we can pin point multiple version, or multiple copies of jars that come in with other jars which were added. Use
<exclusions><exclusion><groupId></groupId><artifactId></artifactId></exclusion></exclusions>
in <dependency> element to exclude the ones which conflict. Always re-run the maven command above after each exclusion if the issue persist.

Sometimes excluding the 2nd logger from the classpath would require too many contortions, and the warning is incredibly annoying. Masking out the standard error as the very beginning of the program does seem to work, e.g.
public static void main(String[] args)
{
org.apache.log4j.Logger.getRootLogger().setLevel(org.apache.log4j.Level.OFF);
PrintStream old = System.err;
System.setErr(new PrintStream(new ByteArrayOutputStream()));
// ... trigger it ...
System.setErr(old);
...
whereby the trigger it part should call some nop function that accesses the logging system and would have otherwise caused the message to be generated.
I wouldn't recommend this for production code, but for skunkworks purposes it should help.

If you're using an old version of Jetty (say Jetty 6), you may need to change the classloading order for the webapp to make it higher priority than the container's. You can do that by adding this line to the container's xml file:
<Set name="parentLoaderPriority">false</Set>

Related

com.oracle.truffle.polyglot.PolyglotImpl (in unnamed module) cannot access class org.graalvm.polyglot.impl.AbstractPolyglotImpl

I tried to extend scaffolded quarkus demo, https://code.quarkus.io/, with polyglot code for GraalVM:
#GET
#Produces(MediaType.TEXT_PLAIN)
public String hello() {
String out = "From JS:";
try (Context context = Context.create()) {
Value function = context.eval("js", "x => x+1");
assert function.canExecute();
int x = function.execute(41).asInt();
out=out+x;
System.out.println(out);
}
return "hello";
}
I added dependencies to pom.xml as suggested here [https://stackoverflow.com/questions/54384499/illegalstateexception-no-language-and-polyglot-implementation-was-found-on-the]
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js</artifactId>
<version>20.1.0</version>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js-scriptengine</artifactId>
<version>20.1.0</version>
</dependency>
<dependency>
<groupId>org.graalvm.truffle</groupId>
<artifactId>truffle-api</artifactId>
<version>20.1.0</version>
</dependency>
But when I run on cmd line
./mvnw clean package
Test fails with exception, which I do not understand.
2020-06-22 19:26:56,328 ERROR [io.qua.ver.htt.run.QuarkusErrorHandler]
(executor-thread-1) HTTP Request to /hello failed, error id: 996b0479-d836-47a5-bbcb-67bd876f9277-1: org.jboss.resteasy.spi.UnhandledException:
java.lang.IllegalAccessError: superclass access check failed:
class com.oracle.truffle.polyglot.PolyglotImpl (in unnamed module #0x7bf61ba2) cannot access class org.graalvm.polyglot.impl.AbstractPolyglotImpl (in module org.graalvm.sdk)
because module org.graalvm.sdk does not export org.graalvm.polyglot.impl to unnamed module #0x7bf61ba2
UPDATE:
It looks like regression in quarkus, https://github.com/quarkusio/quarkus/issues/10226.
App test is passing when used with quarkus 1.2.1 (instead of 1.5.2).
Look into the mvn dependency:tree -- it turns out that org.graalvm.js:js:20.1.0 depends on org.graalvm.sdk:graal-sdk:19.3.1. I'd personally call that GraalVM JS bug.
If you add an explicit dependency on org.graalvm.sdk:graal-sdk:20.1.0, it should work.
(At least it did for me, but I was getting a different error than you, so not sure.)
EDIT: as I was warned about in the comment, it is not true that org.graalvm.js:js:20.1.0 depends on org.graalvm.sdk:graal-sdk:19.3.1. Instead, there must be something else that forces graal-sdk to 19.3.1, perhaps something from Quarkus. Explicitly managing it to 20.1.0 should still help.
are you maybe executing that on GraalVM 19.3.1? That is known to confuse the system. Our strong suggestion is to EITHER run on a GraalVM (which automatically includes a proper version of Graal.js, no further input needed), OR run on a Stock JDK and import the respective JARs from Maven. If you import (a different version of) our Jars from maven on a GraalVM, then you might run into conflicts like that.

Convenience (maven/gradle) dependency to overcome log4j's warning: "no appenders could be found for logger" and just write to console

I am not looking on how to configure log4j so that it actually has an appender, but I rather wondered whether there exists a convenience library (similar to slf4j-simple) which basically just logs everything to console without the need to configure anything else.
Just adding that library and it logs to console.
While writing the question, I remembered, that for sl4fj there actually already is something like that, e.g. there is the Log4j to SLF4J Adapter which basically routes all the log4j logging statements to SLF4J. For version 1.2 such a bridge exits also: org.slf4j:log4j-over-slf4j:1.7.25
From there I can just use slf4j-simple or logback-classic and it will write to console. So for now (until someone offers me a single dependency ;-)) I will use something like the following, which does what I was looking for:
compile "org.slf4j:slf4j-api:1.7.25"
compile "org.slf4j:log4j-over-slf4j:1.7.25"
compile "ch.qos.logback:logback-classic:1.2.3" // or: compile "org.slf4j:slf4j-simple:1.7.25"
For log4j 2 it works as follows:
compile "org.apache.logging.log4j:log4j-to-slf4j:2.11.1"
compile "org.slf4j:slf4j-api:1.7.25"
compile "ch.qos.logback:logback-classic:1.2.3" // or: compile "org.slf4j:slf4j-simple:1.7.25"
Actually in my case I only required the following two (even though the 1.2-log4j-warning was displayed, but probably some other dependencies were already in place as well ;-)):
implementation("ch.qos.logback:logback-classic:1.2.3")
implementation("org.apache.logging.log4j:log4j-to-slf4j:2.11.1")

Error: Could not initialize class ru.yandex.clickhouse.ClickHouseUtil

I'm using clickhouse-jdbc in my java application. And I'm adding it to pom.xml like this:
<dependency>
<groupId>ru.yandex.clickhouse</groupId>
<artifactId>clickhouse-jdbc</artifactId>
<version>0.1.34</version>
</dependency>
And when I run my java application java -jar myapp.jar. It's throwing:
java.lang.NoClassDefFoundError: Could not initialize class
ru.yandex.clickhouse.ClickHouseUtil
And in my packaged jar file, there is also ClickHouseUtil.class. And I'm using Intellij Idea for packaging jar. How can I fix this issue?
The error 'Could not initialize class ....' means that the JVM has already tried and failed to perform static initialization of the class mentioned.
Static initialization of a class involves assigning values to any static fields and running any static { ... } blocks. The class in question is ru.yandex.clickhouse.ClickHouseUtil, and static initialization of this class consists only of setting up the static final field CLICKHOUSE_ESCAPER. This appears to rely on a couple of Guava escaper classes (com.google.common.escape.Escaper and com.google.common.escape.Escapers).
So I suspect that these Guava classes aren't in your packaged JAR file.
It's also worth pointing out that the exception message 'Could not initialize class ....' means that static initialization has already failed. In other words, when this exception is thrown, it is at least the second time the JVM has failed to load the class. It's possible that your app may have reported a more informative error message when the JVM failed to load this class for the first time.

Maven Jaxb Generate Fails When Compiling A Module That Depends On Multiple Modules

I have an Eclipse Maven project consisting of multiple modules, some of which contain Xml schemas that I want to generate classes for (using Jaxb). My project layout is as follows:
schemas\core (pom)
schemas\core\types (jar)
schemas\vehicle (pom)
schemas\vehicle\automobile (jar)
schemas\vehicle\civic (jar)
The projects that contain schemas are:
schemas\core\types (xsd\types.xsd)
schemas\vehicle\automobile (xsd\automobile.xsd)
schemas\vehicle\civic (xsd\civic.xsd)
Some of the modules contain schemas that import schemas from other modules:
automobile.xsd imports types.xsd
civic.xsd imports types.xsd, automobile.xsd
Since the schemas are located in different projects I use a classpath catalog resolver along with catalog files to resolve the location of the schemas.
The automobile project depends on schemas in the types project. Here is the entry in its catalog file (catalog.xml):
<rewriteSystem systemIdStartString="http://schemas/core/types/" rewritePrefix="classpath:xsd/" />
Note the use of classpath:xsd/ to tell the catalog resolver to find the schemas on the classpath.
I also use episodes to prevent the classes in types from being re-generated inside the automobile project. Here is a snippit from my pom.xml:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.8.3</version>
<configuration>
<episodes>
<episode>
<groupId>schemas.core</groupId>
<artifactId>types</artifactId>
<version>1.0-SNAPSHOT</version>
</episode>
<episodes>
<catalog>src/main/resources/catalog.xml</catalog>
<catalogResolver>org.jvnet.jaxb2.maven2.resolver.tools.ClasspathCatalogResolver</catalogResolver>
<extension>true</extension>
....
When I run mvn clean install on automobile project everything works file. The schema types.xsd is resolved on the classpath and the classes are ultimately generated.
Where I run into problems is trying to compile the project civic.
The civic project depends on both types.xsd and automobile.xsd. I use a catalog file (catalog.xml) to define the location of the schemas:
<rewriteSystem systemIdStartString="http://schemas/core/types/" rewritePrefix="classpath:xsd/" />
<rewriteSystem systemIdStartString="http://schemas/vehicle/automobile/" rewritePrefix="classpath:xsd/" />
I use episodes to prevent re-generation of the classes. Here is a snippit from the pom.xml for civic:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.8.3</version>
<configuration>
<episodes>
<episode>
<groupId>schemas.core</groupId>
<artifactId>types</artifactId>
<version>1.0-SNAPSHOT</version>
</episode>
<episode>
<groupId>schemas.vehicle</groupId>
<artifactId>automobile</artifactId>
<version>1.0-SNAPSHOT</version>
</episode>
</episodes>
<catalog>src/main/resources/catalog.xml</catalog>
<catalogResolver>org.jvnet.jaxb2.maven2.resolver.tools.ClasspathCatalogResolver</catalogResolver>
<extension>true</extension>
...
When I try to run mvn clean install on the civic project I run into problems. It complains about not being able to resolve the public/system ids. Here are some of the error messages I get:
Could not resolve publicId [null], systemId [jar:file:/_m2repository/schemas/vehicle/automobile/1.0-SNAPSHOT/automobile-1.0-SNAPSHOT.jar!http://schemas/core/types/types.xsd]
[ERROR] Error while parsing schema(s).Location [].
com.sun.istack.SAXParseException2;
IOException thrown when processing "jar:file:/_m2repository/schemas/vehicle/automobile/1.0-SNAPSHOT/automobile-1.0-SNAPSHOT.jar!http://schemas/core/types/types.xsd".
Exception: java.net.MalformedURLException: no !/ in spec.
....
For some reason it cannot find types.xsd when trying to parse the jar file from the automobile project.
Does anyone know why this might be happening?
Thank you.
Note - I was experimenting around with tying to get things to work and I did find one way. If I remove the episodes from the pom.xml file I no longer get the error, however, the project civic ends up with all the types from the dependent modules (which is something I am tying to avoid by using the episodes).
If you want to see the full catalog.xml and pom.xml files for each project please see the following links:
types: http://pastebin.com/Uym3DY6X
automobile: http://pastebin.com/VQM4MPuW
civic: http://pastebin.com/eGSVGwmE
Author of the maven-jaxb2-plugin here.
I have just released the 0.10.0 version of the maven-jaxb2-plugin. This release fixes the MAVEN_JAXB2_PLUGIN-82 issue which is related to the reported problems.
This was actually NOT a bug in the maven-jaxb2-plugin, but an issue (or, better to say a few issues) in the XJC itself:
https://java.net/jira/browse/JAXB-1044
https://java.net/jira/browse/JAXB-1045
https://java.net/jira/browse/JAXB-1046
These issues cause problems when catalog and binding files are used together. This was also the reason why the Maven artifact resoltion did not work correctly in certain cases.
In the 0.10.0 release, I have implemented workarounds for JAXB-1044 and JAXB-1045. I will try to get my patches to the XJC via pull requests, but you know, I'm not sure, when/if Oracle guys will accept my PRs.
In the maven-jaxb2-plugin I've now implemented quite reliable workarounds. See this test project here:
https://github.com/highsource/maven-jaxb2-plugin/tree/master/tests/MAVEN_JAXB2_PLUGIN-82
This does exactly what you want: resolves schema via catalog AND Maven resolver to the resource from another artifact. Basically, this rewriting:
REWRITE_SYSTEM "http://www.ab.org" "maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a:jar::!"
now works fine.
In case of problems do mvn -X and check the output, you'll also see the statements of the catalog resolver in the log. This might give you hints, what does not work.
Here's another project which uses schemas, bindings and the catalog itself from one central artifact:
https://github.com/highsource/w3c-schemas
Snippets from the POM:
<schemas>
<schema>
<url>http://www.w3.org/1999/xlink.xsd</url>
</schema>
</schemas>
<schemaIncludes/>
<bindings>
<binding>
<dependencyResource>
<groupId>${project.groupId}</groupId>
<artifactId>w3c-schemas</artifactId>
<resource>globalBindings.xjb</resource>
<version>${project.version}</version>
</dependencyResource>
</binding>
</bindings>
<catalogs>
<catalog>
<dependencyResource>
<groupId>${project.groupId}</groupId>
<artifactId>w3c-schemas</artifactId>
<resource>catalog.cat</resource>
<version>${project.version}</version>
</dependencyResource>
</catalog>
</catalogs>
Catalog:
REWRITE_SYSTEM "http://www.w3.org" "maven:org.hisrc.w3c:w3c-schemas:jar::!/w3c"
Binding:
<jaxb:bindings schemaLocation="http://www.w3.org/1999/xlink.xsd" node="/xs:schema">
<jaxb:schemaBindings>
<jaxb:package name="org.hisrc.w3c.xlink.v_1_0"/>
</jaxb:schemaBindings>
</jaxb:bindings>
So how all of this works:
Schemas as well as the catalog and global bindings are stored in the central artifact w3c-schemas.
The project wants to compile the URL http://www.w3.org/1999/xlink.xsd.
The catalog rewrites this URL into the systemId maven:org.hisrc.w3c:w3c-schemas:jar::!/w3c/1999/xlink.xsd. (There's a /w3c/1999/xlink.xsd resource in the w3c-schemas jar).
This systemId is then resolved my the Maven catalog resolver (delivered my the maven-jaxb2-plugin) into the "real" URL which will be some jar:... URL pointing to the resource within the w3c-schemas artifact JAR in the local repository.
So the schema is not downloaded from the Internet but taken from the local resource.
The workaround keep the "original" systemIds, therefor you can customize the schema using its original URL. (The resolved systemId won't be convenient.)
The catalog file and the global bindings file will be the same for all the individual projects, so they're also put into the central artifact and referenced there using the dependencyResource.
I have the same problem. Schema C imports B and A, B imports A. Generating sources for A, works, B is also fine and for C a MalformedUrlException pops up.
I'm still investigating the error but a workaround is to use the systemIdSuffix (Oasis spec 1.1) to match the systemId and rewrite it. You need to do the following:
Remove the 'catalogResolver' element from the plugin configuration in the poms.
Replace the content of the catalog file for the 'automobile' project with the following:
<systemSuffix systemIdSuffix="types.xsd" uri="maven:schemas.core:types!/types.xsd"/>
Replace the content of the catalog file for the 'civic' project with the following:
<systemSuffix systemIdSuffix="types.xsd" uri="maven:schemas.core:types!/types.xsd"/>
<systemSuffix systemIdSuffix="automobile.xsd" uri="maven:schemas.vehicle:automobile!/automobile.xsd"/>
Let me know if this works for you.
I faced similar problems. I used the sample projects found here.
I modified these projects in 2 ways:
1) Have an A project with 2 namespaces and a local catalog file. Have a project B depending on this, using the episode of A in B.
2) Have an A project, a B project and a C project. B relies on A and C relies on B.
In both cases I got the same exception as you. But I started to realize in situation 2 what is happening.
This is the exception:
com.sun.istack.SAXParseException2; IOException thrown when processing "jar:file:/Users/sjaak/.m2/repository/org/tst/b-working/1.0/b-working-1.0.jar!http://www.a1.org/a1/a1.xsd". Exception: java.net.MalformedURLException: no !/ in spec.
So, it tries to resolve namespace http://www.a1.org/a1/a1.xsd relative to project B when building project C. I traced the problem back to com.sun.tools.xjc.reader.internalizerAbstractReferenceFinderImpl, method startElement.
The solution I use is adapting the org.jvnet.jaxb2.maven2:maven-jaxb2-plugin. I used their MavenCatalogResolver (the default one as pointed out above) and made a small change, simply not offering the whole systemId: jar:file:/Users/sjaak/.m2/repository/org/tst/b-working/1.0/b-working-1.0.jar!http://www.a1.org/a1/a1.xsd, but in stead use a pattern that only offers the part after the exclamation mark for resolving.
Here's the code:
package org.jvnet.jaxb2.maven2.resolver.tools;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.text.MessageFormat;
import org.jvnet.jaxb2.maven2.DependencyResource;
import org.jvnet.jaxb2.maven2.DependencyResourceResolver;
import com.sun.org.apache.xml.internal.resolver.CatalogManager;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MavenCatalogResolver extends
com.sun.org.apache.xml.internal.resolver.tools.CatalogResolver {
private final static Pattern PTRN = Pattern.compile("^jar:file:(.*).jar!(.*)$");
public static final String URI_SCHEME_MAVEN = "maven";
private final DependencyResourceResolver dependencyResourceResolver;
private final CatalogManager catalogManager;
public MavenCatalogResolver(CatalogManager catalogManager,
DependencyResourceResolver dependencyResourceResolver) {
super(catalogManager);
this.catalogManager = catalogManager;
if (dependencyResourceResolver == null) {
throw new IllegalArgumentException(
"Dependency resource resolver must not be null.");
}
this.dependencyResourceResolver = dependencyResourceResolver;
}
#Override
public String getResolvedEntity(String publicId, String systemId)
{
String result;
Matcher matcher = PTRN.matcher(systemId);
if (matcher.matches())
{
result = super.getResolvedEntity(publicId, matcher.group(2));
}
else
{
result = super.getResolvedEntity(publicId, systemId);
}
if (result == null) {
return null;
}
try {
final URI uri = new URI(result);
if (URI_SCHEME_MAVEN.equals(uri.getScheme())) {
final String schemeSpecificPart = uri.getSchemeSpecificPart();
try {
final DependencyResource dependencyResource = DependencyResource
.valueOf(schemeSpecificPart);
try {
final URL url = dependencyResourceResolver
.resolveDependencyResource(dependencyResource);
String resolved = url.toString();
return resolved;
} catch (Exception ex) {
catalogManager.debug.message(1, MessageFormat.format(
"Error resolving dependency resource [{0}].",
dependencyResource));
}
} catch (IllegalArgumentException iaex) {
catalogManager.debug.message(1, MessageFormat.format(
"Error parsing dependency descriptor [{0}].",
schemeSpecificPart));
}
return null;
} else {
return result;
}
} catch (URISyntaxException urisex) {
return result;
}
}
}
This actually fixed my problem. I'll investigate a bit more. I've got the feeling there might be some XJC arg that I could use, or perhaps the catalog XML format offers more possibilities.
Hope it helps.

where I should place log4j.properties file to enable debug logging in smslib,when it is added through maven dependencies?

I'm doing some java maven project based on thucydides-jbehave-archetype.
Smslib dependency is added through maven:
<dependency>
<groupId>org.smslib</groupId>
<artifactId>smslib</artifactId>
<version>dev-SNAPSHOT</version>
</dependency>
...
<repositories>
<repository>
<id>smslib-snapshots</id>
<name>SMSLib Repository</name>
<url>http://smslib.org/maven2/snapshots/</url>
</repository>
</repositories>
Among the pure web tests I plan to do some sms sending/receiving; sms code is placed in src/main/java/projectname/gsm package (for instance, page objects are placed in src/main/java/projectname/pages, steps are placed in src/test/java/projectname.jbehave/). I'd like to enable debug messages for smslib, but not for thucydides. However, there was no location where log4j.properties worked for smslib, and there was one location, that resulted in appearing debug messages for thucydides.
You can dump your log4j.properties file in src/main/resources.
To control the log level, just create an appropriate Log4j configuration file.
...
# Print only messages of level WARN or above in the package com.foo.
log4j.logger.com.foo=WARN
...
For more details, please have a look at the Log4j manual.
Can your question be rephrased as:
How do I set two different log levels using properties files for log4j - using two separate files for two classes in different packages?
If this is the case, rimero's answer is a start. But instead of dropping the properties files in src/main/sources, you need to drop each file (defining a different log level) in a directory structure reflecting the package name (for example src/main/projectname/page). Then, you can load each properties file separately using
PropertyConfigurator.configure(URL configURL)
There are a couple of ways to get the url of your properties files, see for example:
How to configure log4j with a properties file
Here is a full example:
public class TestPropertiesFile {
private static final String PREFIX = "projectname/pages";
private static final org.apache.log4j.Logger LOGGER = org.apache.log4j.Logger
.getLogger("projectname.page.SomeClass");
private static String PROPERTIES_PATH;
static {
PROPERTIES_PATH = Thread.currentThread().getContextClassLoader()
.getResource(PREFIX + "/log4j.properties").getPath();
org.apache.log4j.PropertyConfigurator.configure(PROPERTIES_PATH);
}
public static void test() {
LOGGER.info("Logging from: " + PROPERTIES_PATH);
}
}

Resources