We have a plain old java library that is instantiated from many different applications. In this case each application is a web application that all live in the same tomcat container.
Each application logs to its own log file, using its own logger. We want the logs generated by the library, that are pertinent to a specific application, to also go to that applications separate log file.
For this, one way is to allow the application to pass in its logger to the library:
library = new library(Logger applicationsVeryOwnLogger);
And then use that logger, to log all statements in the library. However, this means that the logger is now a class variable in the library, and every class in the library needs a reference to the library to use the right logger.
Are there better ways to do this?
We had a similar need in one of our older applications. The solution we came up with was a ResourceManager that would retrieve resources(Logger, Config files etc) by (context)ClassLoader.
Usually every application deployed as an EAR gets its own ClassLoader and the library can then just call ResourceManager.getLogger() to get the Logger associated with the current Thread/Application. That way you dont need to pass it with every method call in the library (it requires that you can change the library tho).
Register Logger in the init phase of EJB/WebApp(needs to be registered before any call to getLogger):
Retrieve Logger in library(utility method):
This will return the logger for the application(EAR) that is associated with the current thread.
Not limited to Loggers it also works for other resources that you want to share.
Limitations:
wont work if you package multiple applications/EJBs per deployed EAR
ResourceManager and Logging library need to be on the same or a higher ClassLoader than the library and application. If there is an option to bundle then Alexanders approach is cleaner. (we use java.util.logging which is by default on the server level so his approach doesnt work)