Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to merge Log4j2Plugins.dat? #207

Closed
PatrickHuetter opened this issue Apr 21, 2016 · 13 comments
Closed

How to merge Log4j2Plugins.dat? #207

PatrickHuetter opened this issue Apr 21, 2016 · 13 comments

Comments

@PatrickHuetter
Copy link

Regarding to this issue https://issues.apache.org/jira/browse/LOG4J2-954 i would like to know how to merge/concat the Log4j2Plugins.dat with shadowJar?

I already tested some configuration patterns but they didn't work.
For maven users there is a workaround like this https://github.com/edwgiz/maven-shaded-log4j-transformer but i could figure out how to get similar working with gradle.

Best regards

@PatrickHuetter
Copy link
Author

PatrickHuetter commented Apr 21, 2016

Using a custom jar task without shadowJar and downgrading log4j2 dependencies to 2.0.2 seems to work partly (using jd-gui i see the Log4j2Plugin.dat 3 times instead of only 1 time using the shadowJar method):

jar {
    doFirst {
        from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    }

    // This is optional, needed if you have signature problems while starting your created jar.
    // This often happens while including foreign depdendencies wich are signed.
    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'

    // change to your main class with full package name
    manifest.attributes("Main-Class":"com.app.MyApp", 'Class-Path': '/')
}

bildschirmfoto 2016-04-21 um 14 21 30

The fat jar is able to start and log4j2 is able to find the configuration. Now it fails because it can't find the AsyncAppender which seems to be only included in newer log4j2 revisions. which seems to be caused by the missing merging of the *.dat files.

org.apache.logging.log4j.core.config.ConfigurationException: No appenders are available for AsyncAppender async
        at org.apache.logging.log4j.core.appender.AsyncAppender.start(AsyncAppender.java:106)
        at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:168)
        at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:359)
        at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:420)
        at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:138)
        at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:147)
        at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:41)
        at org.apache.logging.log4j.LogManager.getContext(LogManager.java:175)
        at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:426)

UPDATE:
Got it working by upgrading the gelf plugin to 'org.graylog2.log4j2:log4j2-gelf:1.1.0' with downgrade of log4j to 2.0.2.

@johnrengelman
Copy link
Collaborator

You'd need to write your own Transformer class (https://github.com/johnrengelman/shadow/blob/master/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/Transformer.groovy) and then add it to your build using:

shadowJar {
  transform(MyTransformer.class)
}

The workaround you are using is highly non-performant as you are expanding all of your dependencies onto disk using the zipTree method.

@PatrickHuetter
Copy link
Author

Thank you @johnrengelman . I don't use zipTree and the code above anymore. It was only for testing another approach. I got it already working with shadowJar using the steps described in my last post. If i get further problems i'll investigate in writing a Transformer. Best regards

@reutsharabani
Copy link

I encountered the same problem (I think) with log4j versions that are greater than 2.5.

Downgrading log4j to 2.5 made shadow work again.

@TheBoegl
Copy link

TheBoegl commented Jan 4, 2017

@johnrengelman could you include the converted maven-shaded-log4j-transformer like in this gist? This could be a is the solution for TheBoegl/gradle-launch4j#40.

@johnrengelman
Copy link
Collaborator

@TheBoegl if someone wants to submit it as PR, I'd be happy to merge it.

@TheBoegl
Copy link

TheBoegl commented Jan 5, 2017

@johnrengelman I think a own plugin would be better to avoid the log4j2 dependency in the shadow plugin, therefore, my previous comment only hints a workaround.

@TheBoegl
Copy link

TheBoegl commented Jan 6, 2017

I created a gradle plugin, but typo'd to reference this issue.

@johnrengelman
Copy link
Collaborator

@TheBoegl neat. No need for it to be a full plugin though. Could just be a library that a user can add to the buildscript classpath.

@TheBoegl
Copy link

@johnrengelman Thanks. It really is just one class that applies this plugin and adds the transformation. I could not think of an easier use case though you seem to have one in mind. Could you please elaborate on that?

@johnrengelman
Copy link
Collaborator

johnrengelman commented Jan 10, 2017

Your library really only needs the transformer class. You don't need a gradle plugin. so you could do this

buildscript {
  dependencies {
    classpath "com.github.jengelman.gradle.plugins:shadow:1.2.4"
    classpath 'de.sebastianboegl.gradle.plugins:shadow-log4j-transformer:1.0.1'
  }
}

apply plugin: 'com.github.johnrengelman.shadow'

shadowJar {
  transform(de.sebastianboegl.gradle.plugins.shadow.transformers.Log4j2PluginsFileTransformer)
}

@TheBoegl
Copy link

You are absolutely right, hence, I've added the description to the readme. I've thought you meant a much more difficult way...

@Corionis
Copy link

Corionis commented Mar 5, 2024

For those wanting to merge multiple Log4j2Plugins.dat files and any custom log4j plug-ins using the annotation-generated Log4j2Plugins.dat in an Ant script see the GitHub project MergeLog4j2Plugins.

copybara-service bot pushed a commit to bazelbuild/bazel that referenced this issue Dec 9, 2024
In [singlejar](https://github.com/bazelbuild/bazel/tree/master/src/tools/singlejar), add support for combining Log4j2 plugins cache file.

Log4j2 plugins are Java annotations collected by a compiler plugin into .dat files for Log4j2 runtime to find them fast. With correct dependency on a `java_plugin`, Bazel already runs the java plugin compiler correctly. The behavior is correct on `bazel run` JAR, but not on `_deploy.jar` fat jars.

The silent clobbering of files in general, and the example of these Log4j2 .dat files in particular, is discussed in #7330.

- [File structure of Log4j2Plugins.dat files](https://github.com/apache/logging-log4j2/blob/8573ef778d2fad2bbec50a687955dccd2a616cc5/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/processor/PluginCache.java)
- the test data was generated by a python script, happy to commit it as well
- [How to merge Log4j2Plugins.dat?](GradleUp/shadow#207)

I tested this fix in my project using Bazel 7.0.2, compiling `//src:java_tools_prebuilt.zip`, and overriding `@remote_java_tools_darwin_arm64` and `@remote_java_tools_linux`.

Closes #22581.

PiperOrigin-RevId: 704192345
Change-Id: I271f0e4b2db57f5dc24c77ea883c6770f2827ed0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants