So I have read the migration document on how you port code from Log4J to SLF4J Api, but I am still unclear what you do when your legacy code 3rd party dependencies have a dependency on Log4J. I obviously, don’t want my final executable jar file to contain the Log4J jar, so I can of course add an exclusion in my project pom file, but isn’t that a big risk, as the 3rd party code could in theory be using aspects of Log4J that are not covered via the Log4J-over-slf4j implementation and you then run the risk of a runtime exception as the required binaries are not present on the classpath?
Or maybe I am wrong and instead of excluding the Log4J jar file, you just make sure that your classpath definition has log4j-over-slf4j before that of Log4j.
Advertisement
Answer
Obviously, don’t want my final executable jar file to contain the Log4J jar.
Not necessarily so. There is another way. You could use a hybrid of slf4j + whatever logging backend for your code, and continue to use log4j for the problematic dependencies. You will then end up with two sets of log files. But that is not the end of the world …
If you are doing this to deal with log4j vulnerabilities, they can be fixed or mitigated in other ways, depending on whether you are talking about log4j 1.2.x or log4j 2.x. The details are in https://logging.apache.org/log4j/2.x/security.html
… so I can of course add an exclusion in my project pom file, but isn’t that a big risk, as the 3rd party code could in theory be using aspects of Log4J that are not covered via the Log4J-over-slf4j implementation and you then run the risk of a runtime exception as the required binaries are not present on the classpath?
Yes. There is a risk. But you should be able to address that by testing your code. The risk only becomes a real problem if the 3rd-party library is actually using log4j API methods that the bridge code doesn’t implement. If it does, you should quickly see class loader errors when your code attempts to use the affected parts of the 3rd party library:
- The problem may not exist at all in the library codebase1.
- The problem may be isolated to parts of the library that your application doesn’t use.
Either way … if you test your application thoroughly you should be able to tell if this is a real issue … or if you are just worrying about a hypothetical problem.
If it does turn out that the bridging approach doesn’t work then you have a number of alternatives:
- Update the dependencies to a newer version of the library that uses slf4j, or log4j2, or something else that is acceptable.
- Incentivize the library supplier / vendor to fix their problem with legacy logging; e.g offer to pay them, or threaten to cancel your support contract, or …
- See if it is feasible to fork the library and port it to use a more modern logging solution.
- See if it is feasible to fork the log4j-over-slf4j bridge library and add support for the missing log4j APIs. (The feasibility will depend what is missing and what the 3rd-party library needs.)
- Ditch the dependency and look for something better. There will often be other long-term benefits in doing that.
- Employ a contractor who has the skills and confidence to sort out the problem for you.
1 – It would be possible to determine this by forensically examining the 3rd-party library source code, or its .class
files to see which logging classes and methods it references.