What's the best approach in jar/library creation? - java

I need to create jar/library that does some stuff and writes some logs. For logs I was thinking about java.util.logging.Logger vs Logback. So the question is:
Should I prefer using java out-of-the-box logging or it's totally fine to include some third-party tools?
Or it should be purely the matter of my needs and which one to use doesn't really matter?

Use a facade, like slf4j. Think of it from the point of view of the person using your jar in their application. They will want all the logging going to one place, whether it is logging for your jar or for the rest of the application, they will not want to configure your library's logging separately.
Using a logging facade means your library writes to whatever log the rest of the application uses. The application should be in charge of logging, not your jar.
For which facade to use, slf4j seems like a better choice, commons logging can get in trouble where multiple classloaders are involved. See Difference between Simple Logging Facade for Java and Apache Commons Logging

One can use System.Logger
System.Logger instances log messages that will be routed to the underlying logging framework the LoggerFinder uses. System.Logger instances are typically obtained from the System class, by calling System.getLogger(loggerName) or System.getLogger(loggerName, bundle).
Loggers across libraries always were a pain. Java.util.logging incorporated Logging into the Standard Edition. Since Java 9 there is a Standard Edition way to integrate loggers.
This leaves the choice to the library user. No longer a mix, version blues, etcetera. The exact logger in a straight application could be java util Logger.

Related

Logging Method for Spring Based Library

I created a library using Java & Maven that contains some common Spring functionality for reuse in various Spring-Based projects.
The library will obviously need to log error/information messages. Spring allows the developer to use whichever logging library they prefer, how do I make my library do the same?
Spring uses commons-logging which is a logging facade that allows you to write logging code without knowing what is the actual logging framework.
Depending on what you have configured, the commons-logging will then channel the logging messages to the actual implementation. This allows you to write your code using commons-logging, and the users to use any logging framework supported by commons-logging.
Personally I would go with slf4j (Simple Logging Facade 4 Java) which is similar to commons-logging, but newer and functions in pretty much the same way.
It's also possible to bridge different libraries or facades, so that even if libraries use different logging frameworks they will always end up in the logger of your choice. Looking to the monitor to my right there are bridge libraries as follows: jcl-over-slf4j (commons-logging to slf4j), log4j-over-slf4j and jul-to-slf4j (java.util.logging to slf4j).
Note: See the link in comments for more information about how slf4j = good, JCL = bad ;)

How do Log4j, commons-logging, JDK-Logging and SLF4J relate to each other?

Are they alternatives, dependencies, APIs or implementations of each other?
And why do they exist?
Ah, logging frameworks in Java. Your question mixes 2 different types of libraries:
log4j and JDK logging are libraries for handling logging
Commons Logging and SLF4J are logging facades: you still need a real logging implementation (like log4j)
If you are writing a library that will be used in someone else's system, then you should use a logging facade because you do not know which logging framework they will use. In this case use SLF4J (Commons Logging is older and has some classloader issues).
If you control the whole application and can dictate which logging framework to use, you are free to choose your own preference. My preferred solutions are (in order of preference):
Logback
log4j
JDK logging (in my opinion, a case of 'not invented here' by SUN)
I've been looking into this recently too. I've been using Log4J for years with Commons Logging and recently switched to SLF4J.
Log4j
Log4j is a framework for actually doing the log writing/distribution. It's extremely flexible: you can direct it to send log messages to files, syslog, remote monitoring, etc. You can also configure multiple loggers, logging categories, include context in entries, and so on. It's one of the most popular logging systems.
JDK Logging
The built-in JDK logging (which I've never used, to be honest) was added in JDK 1.4.2. From what I gather, it's not very popular because it's not as flexible as Log4j, but I'd welcome comments :).
Commons Logging and SLF4j
Both of these are façades on top of various logging frameworks that present a common interface for your application. For example, you can use CL/SLF4J in your application, and they will automatically detect an underlying logger implementation (Log4J, JDK logging, or a built-in logger that just delegates to System.err.println()). The benefit is that you or your end user can decide to switch out the underlying logging implementation at will, and they greatly simplify your implementation by removing many of the complexities of Log4J and JDK logging.
Most often you will see them layered.
SLF4J is purely an abstraction layer and is not, in itself, used for the actual outputting of logging but used by you in your code to log messages.
A typical setup is to use SLF4J to log in your code, then use log4j as the underlying "output" layer using an appropriate slf4j->log4j bridge (a jar you just include on your classpath). In order to merge logging from different sources, various bridges exist. For instance, many app servers (like tomcat) will use JDK-logging to avoid forcing a "non standard" logging framework on the deployed applications. For that purpose, slf4j has a bridge that will pick up all output from JDK-logging. So, this could be a stack
JDK-logging <- Your app-server or framworks might log using this
|
(JDK->Slf4j bridge)
|
Slf4j <- your application logs using Slf4j
|
(Slf4j->log4j bridge)
|
log4j <- log4j is just responsible for outputting to the appenders you configure (file, console etc)
SLF4J just is a generic API with different back-ends (any other logging system). Log4j and commons-logging (CL) different logging libraries, CL is a fossil. But they all have a fatal flaw, so sun have invented JDK logging.
As for me, I prefer SLF4J as most flexible and logback as a backend for it. Logback is most modern and have a lot nice features.

set the way log is written using Commons-logging

Can I set the way log is written using Commons-logging instead of log4j?
I really want to use commin-logging due to the spec.
No, you can't. To quote from the documentation itself:
JCL provides only a bridge for writing log messages. It does not (and will not) support any sort of configuration API for the underlying logging system.
This is by design. The idea is to use a common logging API while being able to use any underlying log library that you want. You will still have to configure that underlying library.
Commons-logging is just a bridge between your application and the underlying logging system so as Joachim points out you cannot use it for configuration.
Also doesn't stop you using log4j, you still need an underlying logging implementation.
Also might want to look at slf4j as discussed here http://helpdesk.objects.com.au/java/which-logging-framework

java logging vs Log4j in Spring framework. Which one is the most suitable

We are developing a web-based application in Java using the Spring framework. We are wondering which Logging system would be the most appropriate for it, whether Log4j or JUL (java.util.Logging), which is integrated with jdk. As far as I'm concerned, the former is more popular among developers and offers higher customization options, but I'm not sure which is simpler to adapt with spring.
any help will be appreciated.
thanks!
Before you start with log4j, look at logback. Log4j shouldn't be used for new projects anymore. If you have legacy code that needs any logging framework, use slf4j to make the old code talk to logback (or log4j if you must).
The main reasons you should not use JUL is that it implements the bare minimum that you need for logging, the configuration is hard at best and, if you use any component that doesn't use it, you'll have to deal with two logging frameworks.
Regardless of which logging framework you use in your own code, as far as I can remember, Spring has a hard dependency on commons-logging. You can still use whatever you like for your own logging (I'd recommend SLF4J as your facade, with logback as your implementation), but Spring internally needs commons-logging. Whether you want to depend on multiple frameworks is your choice; it shouldn't prove problematic.
Spring uses commons logging, which is a log abstraction facility but has issues that sl4j doesn't have. Hibernate moved to slf4j - I would like to see spring do the same, but I don't think they have any plans in this regard.
So as long as your log abstraction facility (use slf4j) logs to the same logging framework as you've configured commons logging in spring, then you're good. One log configuration for both. You might find an adapter for logback for commons and slf4j.
Since the other responses didn't actually answer your question, I thought I'd have a stab at it.
Firstly, java.util.logging is horrible. It's a pain to use, and a pain to configure. Log4J is nicer on both counts. However, you should pick whichever one you're most comfortable with. Spring uses commons-logging, which in turn will use either log4j (if found on the classpath) or java.util.logging otherwise. In otherwords, if your application already has log4j present, then Spring will effectively use that, and so should you. If log4j is not already present, then either use java.util.logging (if you choose to), or add log4j to your classpath and use that.

Compare log4j and Logger

How does The JDK's Logger compare to Apache log4j?
Which one is better for new projects that target Java 6? How do they compare in terms of flexibility and configurability?
To my mind the only thing the JDK Logger has going for it is that it is part of the JDK, so it doesn't add an external dependency. If the choice is only between those two, I'd go with Log4j. It still has better support in terms of appenders, the number of people who know it (in my anecdotal observations), and a better API (that is subjective as well).
Starting a project today, the most tempting thing to do is go with slf4j and deffer the decision - you can always plug in a different framework underneath slf4j by just changing the classpath.
That being said there are other options (such as Log5j) that take advantage of the latest Java language features. I'd recommend taking a long look Logback (from one of the main programmers of Log4j, as is slf4j).
I've never used the direct JDK logger, but for a new project I'd highly reccomend Logback,
designed as a successor for log4j. Some of the very nice things you can do with it:
printf style parameter building, no more messy concatenating strings protected by if logger.isDebugEnabled() guards.
go from
if (log.isDebugEnabled())
{
log.warn (i + "many ints,"+ l+"many longs");
}
to
log.debug("{} many ints, {} many longs", i, l);
very flexible config, including configurations that will print traces. The config is xml, but their site includes a utility that will generate an xml config from your log4j config to get you started.
Downside - lots of packages require log4j anyway, since it's so common, so your project may need to include 2 logging packages.
For a new project I would strongly recommend the slf4j project which provides generic frontend to several logger frameworks.
The {}-syntax described by Steve B is present in slf4j too (same author) so you get all the benefits regardless of backend, and STILL get the backend independency. Also a log4j bridge is available so existing code transparently can use slf4j. It is really nice.
For actual backend, logback is nice but you may already have invested in log4j - this is easily leveragable.
I would recommend the JDK logging API. I have used it for many years, without any problem whatsoever. It's part of the JDK, so no extra jar is required. The distinctions between log4j and JDK logging are small, and, in my opinion, don't justify the use of log4j.
Standard API vs log4j
A common question asked by Java developers is:
Why we should use log4j logging framework when Java provides an API
for logging. The java API can be accessed by (java.util.logging)?
Log4j has following advantages over standard logging API:
log4j provides robust logging
log4j has more features available than standard logging API
configuring and using log4j is easier
log4j also has a much more robust formatting system
many add-on programs and handlers are available for log4j
I struggled with this question several times; with jdk7 and jdk8; java logging super fast and slick, but only thing we need to put programmer hat while configuring.
To log to multiple file destiantions, we neeed to create signare classes extending FielHandler and use them in properties file to configure, this kind intricacies appears time consuming but once you get hang efficiency and reliability are awesome.

Categories

Resources