Log4j 2
  1. Log4j 2
  2. LOG4J2-235

Dependency on tools.jar and jconsole

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0-beta5
    • Fix Version/s: 2.0-beta6
    • Component/s: Core
    • Labels:
      None
    • Environment:

      Windows 7, 64 bit, Maven 3.0.5, Java 1.6

      Description

      Hello,

      when switching from 2.0-beta4 to 2.0-beta5 I something irritating that in the dependency hierarchy of my project. For log4j2-core there were transitive dependencies on tools.jar and jsconsole which had not been there.

      This looks like a bug and an as a consequence requires a JDK instead of a JRE (at least due to the tools.jar which does not exist in Java 1.6 JRE). If these dependencies are really required, it should be clearly stated.

        Issue Links

          Activity

          Hide
          Nick Williams added a comment -

          I noticed that the other day, too, and almost filed a bug for it. Specifically, this is related to the JMX implementation in Log4j2 (http://markmail.org/thread/flnzsojwv47ohf4q). However, as Ralph stated (http://markmail.org/thread/fbs5huavd4zkdz7c), extra dependencies should not be drug in. This made me think, "well, additional dependencies have been drug in and shouldn't have."

          However, it's important to note that these transitive dependencies system dependencies that are resolved at runtime and are not, for example, packaged with your WAR file if you're creating a web application. Other runtime dependencies would normally be shipped in your WAR file. So the inconvenience here is really only noticed if your IDE is transparent about what it's downloading. I don't BELIEVE it actually affects anything at runtime.

          However, it would be great if Remko could shed some light on this. I'm not exactly clear about how the JMX support he added to Log4j2 would work unless the application was running in a JDK instead of a JRE.

          Show
          Nick Williams added a comment - I noticed that the other day, too, and almost filed a bug for it. Specifically, this is related to the JMX implementation in Log4j2 ( http://markmail.org/thread/flnzsojwv47ohf4q ). However, as Ralph stated ( http://markmail.org/thread/fbs5huavd4zkdz7c ), extra dependencies should not be drug in. This made me think, "well, additional dependencies have been drug in and shouldn't have." However, it's important to note that these transitive dependencies system dependencies that are resolved at runtime and are not, for example, packaged with your WAR file if you're creating a web application. Other runtime dependencies would normally be shipped in your WAR file. So the inconvenience here is really only noticed if your IDE is transparent about what it's downloading. I don't BELIEVE it actually affects anything at runtime. However, it would be great if Remko could shed some light on this. I'm not exactly clear about how the JMX support he added to Log4j2 would work unless the application was running in a JDK instead of a JRE.
          Hide
          Remko Popma added a comment -

          These are compile time dependencies (to build the log4j binaries), not runtime dependencies. Once you have the log4j jar files you should not need tools.jar or jconsole.jar to compile your project. At least I think not, I don't have much maven experience.

          Jconsole classes in core are only used when running the JMX gui as a JConsole plugin.

          I can remove the dependency on tools.jar from core/pom.xml, that was probably a mistake on my part anyway.

          Show
          Remko Popma added a comment - These are compile time dependencies (to build the log4j binaries), not runtime dependencies. Once you have the log4j jar files you should not need tools.jar or jconsole.jar to compile your project. At least I think not, I don't have much maven experience. Jconsole classes in core are only used when running the JMX gui as a JConsole plugin. I can remove the dependency on tools.jar from core/pom.xml, that was probably a mistake on my part anyway.
          Hide
          Nick Williams added a comment -

          Compile time dependencies would, by nature, also be runtime dependencies.

          If this compiles without tools.jar, then tools.jar definitely needs to be removed as a dependency.

          As far as the JMX classes, my (limited) understanding of JMX is that there would be two parts: the "server-side" code (that is, the code running within the application that is using Log4j, and that is running a JMX server) and the "client-side" code (the JConsole plugin). I think packaging these in the same artifact/JAR might not be correct.

          I definitely think that the "server-side" code should be in the log4j-core artifact. This makes sense. However, the JConsole (GUI) code would never be used within the logging application (as far as I can tell). I think this could serve as an argument for moving the JConsole plugin code into a log4j-jconsole-plugin artifact. If the JConsole plugin/GUI code is the only code that depends on jconsole.jar, I think that makes a STRONG argument for moving the JConsole plugin code into a log4j-jconsole-plugin artifact.

          Show
          Nick Williams added a comment - Compile time dependencies would, by nature, also be runtime dependencies. If this compiles without tools.jar, then tools.jar definitely needs to be removed as a dependency. As far as the JMX classes, my (limited) understanding of JMX is that there would be two parts: the "server-side" code (that is, the code running within the application that is using Log4j, and that is running a JMX server) and the "client-side" code (the JConsole plugin). I think packaging these in the same artifact/JAR might not be correct. I definitely think that the "server-side" code should be in the log4j-core artifact. This makes sense. However, the JConsole (GUI) code would never be used within the logging application (as far as I can tell). I think this could serve as an argument for moving the JConsole plugin code into a log4j-jconsole-plugin artifact. If the JConsole plugin/GUI code is the only code that depends on jconsole.jar, I think that makes a STRONG argument for moving the JConsole plugin code into a log4j-jconsole-plugin artifact.
          Hide
          Nick Williams added a comment -

          So, just to be clear, my suggestion is:

          • log4j-core contains most classes from org/apache/logging/log4j/core/jmx/ (those classes required to provide statistics through the JMX server)
          • log4j-jconsole-plugin contains the GUI-related classes from org/apache/logging/log4j/core/jmx/ (those classes required to provide the GUI plugin in the JConsole window)
          Show
          Nick Williams added a comment - So, just to be clear, my suggestion is: log4j-core contains most classes from org/apache/logging/log4j/core/jmx/ (those classes required to provide statistics through the JMX server) log4j-jconsole-plugin contains the GUI-related classes from org/apache/logging/log4j/core/jmx/ (those classes required to provide the GUI plugin in the JConsole window)
          Hide
          Remko Popma added a comment -

          Removed dependency on tools jar from core/pom.xml (revision 1478623). No compilation issues on Windows.

          About creating a separate module for the jconsole plugin, this would mean Yet Another Jar.
          What problem are we trying to solve?

          Show
          Remko Popma added a comment - Removed dependency on tools jar from core/pom.xml (revision 1478623). No compilation issues on Windows. About creating a separate module for the jconsole plugin, this would mean Yet Another Jar. What problem are we trying to solve?
          Hide
          Nick Williams added a comment -

          Glad to hear tools.jar wasn't actually needed.

          Part of the issue is classpath pollution. By putting jconsole.jar on the classpath in the core JAR, other Log4j developers could accidentally use classes from jconsole.jar within other features in the core module. This could have negative consequences for the end-user (granted, that would be detected and corrected pretty quickly).

          The other problem, however, is JAR pollution. The JConsole GUI plugin classes in log4j-core will never be used in applications that normally use log4j-core. For that matter, log4j-core and all other artifacts in Log4j right now are intended to be Maven central artifacts or otherwise libraries that are packaged with the resulting application. But the JConsole GUI plugin classes are NOT intended for that. They will be have to be manually downloaded and placed somewhere (usually on an application administrator's computer) from where they can be put on the classpath when running JConsole. This is a very different context and a very different need. The log4j-jconsole-plugin wouldn't even need to be published in Maven central (though there would be no harm in doing so). I don't think this creates the "Yet Another Jar" problem that it sounds like. It's not "Yet Another Jar" that would ever go in an application.

          Just my $0.02.

          Show
          Nick Williams added a comment - Glad to hear tools.jar wasn't actually needed. Part of the issue is classpath pollution. By putting jconsole.jar on the classpath in the core JAR, other Log4j developers could accidentally use classes from jconsole.jar within other features in the core module. This could have negative consequences for the end-user (granted, that would be detected and corrected pretty quickly). The other problem, however, is JAR pollution. The JConsole GUI plugin classes in log4j-core will never be used in applications that normally use log4j-core. For that matter, log4j-core and all other artifacts in Log4j right now are intended to be Maven central artifacts or otherwise libraries that are packaged with the resulting application. But the JConsole GUI plugin classes are NOT intended for that. They will be have to be manually downloaded and placed somewhere (usually on an application administrator's computer) from where they can be put on the classpath when running JConsole. This is a very different context and a very different need. The log4j-jconsole-plugin wouldn't even need to be published in Maven central (though there would be no harm in doing so). I don't think this creates the "Yet Another Jar" problem that it sounds like. It's not "Yet Another Jar" that would ever go in an application. Just my $0.02.
          Hide
          Remko Popma added a comment -

          Sebastian,
          I'm trying to understand your use case.
          Do you want to build your application with Maven using only a JRE and no JDK?

          Show
          Remko Popma added a comment - Sebastian, I'm trying to understand your use case. Do you want to build your application with Maven using only a JRE and no JDK?
          Hide
          Ralph Goers added a comment -

          jconsole.jar should definitely not be a required dependency. Optional, maybe. I tend to think that moving the Jconsole support to a separate jar project makes sense since it only has value within jconsole.

          Show
          Ralph Goers added a comment - jconsole.jar should definitely not be a required dependency. Optional, maybe. I tend to think that moving the Jconsole support to a separate jar project makes sense since it only has value within jconsole.
          Hide
          Scott Deboy added a comment -

          Is it fair to say 'gui related things' are a bridge-too-far when it comes to core? Pretty much everything else that's optional is fair game? I'd be ok with that.

          Show
          Scott Deboy added a comment - Is it fair to say 'gui related things' are a bridge-too-far when it comes to core? Pretty much everything else that's optional is fair game? I'd be ok with that.
          Hide
          Ralph Goers added a comment -

          I can think of a few other things but in general that is fair.

          Show
          Ralph Goers added a comment - I can think of a few other things but in general that is fair.
          Hide
          Remko Popma added a comment -

          Perhaps my Maven inexperience is getting in the way here.
          Let me try to understand.
          We need jconsole to build log4j, but once these jars have been created, anyone can build their project with just the log4j jars, no? Or does maven now impose a dependency on jconsole on anyone who has a project that uses log4j? And would making this dependency "optional" remove that problem for projects that use log4j?

          Show
          Remko Popma added a comment - Perhaps my Maven inexperience is getting in the way here. Let me try to understand. We need jconsole to build log4j, but once these jars have been created, anyone can build their project with just the log4j jars, no? Or does maven now impose a dependency on jconsole on anyone who has a project that uses log4j? And would making this dependency "optional" remove that problem for projects that use log4j?
          Hide
          Ralph Goers added a comment -

          Maven has different dependency scopes. See http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope Compile scope means the dependency is required to compile, and therefore also to run. If you mark it as optional then it won't be pulled in as a transitive dependency. Requiring jconsole.jar for core would be similar to requiring an eclipse jar or similar. An application running as a server would never want that jar included and it really doesn't make much sense to have the JConsole UI classes in core.

          Show
          Ralph Goers added a comment - Maven has different dependency scopes. See http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope Compile scope means the dependency is required to compile, and therefore also to run. If you mark it as optional then it won't be pulled in as a transitive dependency. Requiring jconsole.jar for core would be similar to requiring an eclipse jar or similar. An application running as a server would never want that jar included and it really doesn't make much sense to have the JConsole UI classes in core.
          Hide
          Sebastian Oerding added a comment - - edited

          Hello,

          actually our use case IS a commercial application running on a server (but not packaged as a WAR). Hence we could define a JDK as system requirements. However currently a JRE is sufficient and to formulate a requirement for a JDK instead just due to two transitive dependencies that are actually not needed makes me feeling uncomfortable.

          Besides just feeling uncomfortable I totally agree with Nick Williams (class path pollution / usage of classes that are not intended to be used by someone just using log4j2).

          About the runtime/compile time dependencies: The scopes of dependencies form a hierarchy. Thus as Nick stated a jar that is required for compilation is also required at runtime.

          You can try the following: Take a jar with a transitive dependency for example on log4j (1.2). Then use the Maven mechanism to exclude transitive dependencies. However you may have a project with several jars depending on log4j. Then exclude all transitive dependencies for log4j and remove the declared direct dependency on log4j if there is any. Once the last dependency is left you'll run into problems.

          For example in Eclipse you would at first get errors such as "Class XYZ is missing. It is indirectly referenced by some .class files" (I do not have the exact wording in my mind at this moment). Furthermore your auto completion would fail on any of these log4j classes.

          Howver everything starts to get more complex if using reflection. By reflection you may call classes at runtime given by strings (class names) => no compile time dependency but runtime dependency. At the moment I'm not totally sure if it can go the other way round.
          I don't think so cause at some point you must call a specific class if you want to use it otherwise there should be no dependency at all. But using service provider frameworks or using the JDK 6 compiler API (you can give a string at runtime and compile it to a Java class ...) or doing your own code instrumentation things are getting rather complex. Thus having removed the dependency on tools.jar and do not encountering any compilation issues is not a real proof (however it might be good enough as there will be some testing / continous integration before a release).

          This leads to my conclusion: If there is a transitive dependency on something, I may exclude it and everything may compile fine. Furthermore everything may run fine for some time but may crash at one point when a specific class is invoked using reflection. Having there no transitive dependency gives a me kind of safety (as I'm assuming that the declared dependencies are correct) and avoids me spending time on wondering issues that might be irrelevant.

          Show
          Sebastian Oerding added a comment - - edited Hello, actually our use case IS a commercial application running on a server (but not packaged as a WAR). Hence we could define a JDK as system requirements. However currently a JRE is sufficient and to formulate a requirement for a JDK instead just due to two transitive dependencies that are actually not needed makes me feeling uncomfortable. Besides just feeling uncomfortable I totally agree with Nick Williams (class path pollution / usage of classes that are not intended to be used by someone just using log4j2). About the runtime/compile time dependencies: The scopes of dependencies form a hierarchy. Thus as Nick stated a jar that is required for compilation is also required at runtime. You can try the following: Take a jar with a transitive dependency for example on log4j (1.2). Then use the Maven mechanism to exclude transitive dependencies. However you may have a project with several jars depending on log4j. Then exclude all transitive dependencies for log4j and remove the declared direct dependency on log4j if there is any. Once the last dependency is left you'll run into problems. For example in Eclipse you would at first get errors such as "Class XYZ is missing. It is indirectly referenced by some .class files" (I do not have the exact wording in my mind at this moment). Furthermore your auto completion would fail on any of these log4j classes. Howver everything starts to get more complex if using reflection. By reflection you may call classes at runtime given by strings (class names) => no compile time dependency but runtime dependency. At the moment I'm not totally sure if it can go the other way round. I don't think so cause at some point you must call a specific class if you want to use it otherwise there should be no dependency at all. But using service provider frameworks or using the JDK 6 compiler API (you can give a string at runtime and compile it to a Java class ...) or doing your own code instrumentation things are getting rather complex. Thus having removed the dependency on tools.jar and do not encountering any compilation issues is not a real proof (however it might be good enough as there will be some testing / continous integration before a release). This leads to my conclusion: If there is a transitive dependency on something, I may exclude it and everything may compile fine. Furthermore everything may run fine for some time but may crash at one point when a specific class is invoked using reflection. Having there no transitive dependency gives a me kind of safety (as I'm assuming that the declared dependencies are correct) and avoids me spending time on wondering issues that might be irrelevant.
          Hide
          Remko Popma added a comment -

          Ralph, thank you for the link.
          The dependency on jconsole should obviously have been optional from the beginning.
          Apologies that my lack of Maven experience caused inconvenience.

          I made the dependency on jconsole optional in core/pom.xml (revision 1478758).
          This should resolve Sebastian's immediate issue.

          The consensus seems to be to move the 4 jmx gui classes into a separate module. I'll do that at some later point.

          Show
          Remko Popma added a comment - Ralph, thank you for the link. The dependency on jconsole should obviously have been optional from the beginning. Apologies that my lack of Maven experience caused inconvenience. I made the dependency on jconsole optional in core/pom.xml (revision 1478758). This should resolve Sebastian's immediate issue. The consensus seems to be to move the 4 jmx gui classes into a separate module. I'll do that at some later point.
          Hide
          Nick Williams added a comment -

          Alright, let me clear a few things up, because it sounds like there may be some confusion, and that's the last thing I want.

          First of all, tools.jar probably isn't ever required. It contains utilities for running the compiler, JavaDoc, and other normally-executable utilities from the Java API instead of the command line. It doesn't contain any JMX or JConsole classes that I can see. So I think removing it as a dependency is safe.

          Now as far as I can tell jconsole.jar is required for compiling and running the GUI JMX classes. Even if it WERE required for the other JMX classes, it would never be required to COMPILE an application that was using Log4j. It would only be required to RUN an application using Log4j (which means the running application would have to be running in a JDK).

          Of course, we certainly don't want to introduce a dependency on a JDK in order to use Log4j. As I said, my suspicion is that these JDK-only classes are ONLY required for the GUI classes. However, the best way to ensure this is, as many have agreed here, to move the GUI classes into a separate submodule (log4j-jconsole-plugin, or similar). Then, we should be able to remove the jconsole.jar dependency from the Core since it would only be required in the submodule.

          Hope this clears a few things up.

          Show
          Nick Williams added a comment - Alright, let me clear a few things up, because it sounds like there may be some confusion, and that's the last thing I want. First of all, tools.jar probably isn't ever required. It contains utilities for running the compiler, JavaDoc, and other normally-executable utilities from the Java API instead of the command line. It doesn't contain any JMX or JConsole classes that I can see. So I think removing it as a dependency is safe. Now as far as I can tell jconsole.jar is required for compiling and running the GUI JMX classes. Even if it WERE required for the other JMX classes, it would never be required to COMPILE an application that was using Log4j. It would only be required to RUN an application using Log4j (which means the running application would have to be running in a JDK). Of course, we certainly don't want to introduce a dependency on a JDK in order to use Log4j. As I said, my suspicion is that these JDK-only classes are ONLY required for the GUI classes. However, the best way to ensure this is, as many have agreed here, to move the GUI classes into a separate submodule (log4j-jconsole-plugin, or similar). Then, we should be able to remove the jconsole.jar dependency from the Core since it would only be required in the submodule. Hope this clears a few things up.
          Hide
          Remko Popma added a comment -

          Nick, I'm not disagreeing with you.
          I removed tools.jar as soon as it was pointed out.
          I made jconsole.jar optional as soon as I understood how this transitive dependency thing works in maven.

          There is no (and never was any) dependency on JDK classes for anyone using log4j.
          The class in question is only used when you run
          $JAVA_HOME/bin/jconsole pluginpath log4j-core<version>.jar
          (and you would need a JDK to run that command anyway)

          Removing tools.jar and making jconsole.jar optional was high-priority as it was affecting users.

          Moving the JMX GUI classes into a separate submodule (I'd like to call it log4j-jmx-gui) is on the todo list, but not at the top anymore. There are a handful of bugs and there's your DB appenders patch that I all consider higher priority and I plan to look at those first before the module reshuffling.

          Let me know if you think I am prioritizing things wrong.

          Show
          Remko Popma added a comment - Nick, I'm not disagreeing with you. I removed tools.jar as soon as it was pointed out. I made jconsole.jar optional as soon as I understood how this transitive dependency thing works in maven. There is no (and never was any) dependency on JDK classes for anyone using log4j. The class in question is only used when you run $JAVA_HOME/bin/jconsole pluginpath log4j-core <version>.jar (and you would need a JDK to run that command anyway) Removing tools.jar and making jconsole.jar optional was high-priority as it was affecting users. Moving the JMX GUI classes into a separate submodule (I'd like to call it log4j-jmx-gui) is on the todo list, but not at the top anymore. There are a handful of bugs and there's your DB appenders patch that I all consider higher priority and I plan to look at those first before the module reshuffling. Let me know if you think I am prioritizing things wrong.
          Hide
          Nick Williams added a comment -

          No, I think that's a fair order of priorities. Sounds good.

          Show
          Nick Williams added a comment - No, I think that's a fair order of priorities. Sounds good.
          Hide
          Remko Popma added a comment -

          Created ticket LOG4J2-237 for the follow-up work.

          Show
          Remko Popma added a comment - Created ticket LOG4J2-237 for the follow-up work.
          Hide
          Nick Williams added a comment -

          Good idea.

          Show
          Nick Williams added a comment - Good idea.
          Hide
          Remko Popma added a comment -

          Ralph, I'd like to mark this ticket as "Resolved" but I cannot see that button (perhaps because it wasn't assigned yet?). Can you give me the right to assign issues to myself?

          Sebastian, this is now fixed in trunk. Can you verify and close this ticket? Thanks!

          Show
          Remko Popma added a comment - Ralph, I'd like to mark this ticket as "Resolved" but I cannot see that button (perhaps because it wasn't assigned yet?). Can you give me the right to assign issues to myself? Sebastian, this is now fixed in trunk. Can you verify and close this ticket? Thanks!
          Hide
          Ralph Goers added a comment -

          I've changed your role in Jira to committer. Please let me know if that gives you the rights you need.

          Show
          Ralph Goers added a comment - I've changed your role in Jira to committer. Please let me know if that gives you the rights you need.
          Hide
          Remko Popma added a comment -

          Sebastian, this is now fixed in trunk. Can you verify and close this ticket? Thanks!

          Show
          Remko Popma added a comment - Sebastian, this is now fixed in trunk. Can you verify and close this ticket? Thanks!
          Hide
          Sebastian Oerding added a comment -

          Hi,

          I switched to 2.0-beta6 and the dependencies on the JDK (tools.jar and jconsole.jar) are removed.

          Thx for your immediate reaction.

          By the way is there a proper place for questions? I noticed one thing, probably it's a misconfiguration on my side but it might be a completely different bug. However I do not won't to open a new issue until I'm sure about it.

          With regards
          Sebastian

          Show
          Sebastian Oerding added a comment - Hi, I switched to 2.0-beta6 and the dependencies on the JDK (tools.jar and jconsole.jar) are removed. Thx for your immediate reaction. By the way is there a proper place for questions? I noticed one thing, probably it's a misconfiguration on my side but it might be a completely different bug. However I do not won't to open a new issue until I'm sure about it. With regards Sebastian
          Hide
          Sebastian Oerding added a comment -

          Switching to the new version (2.0-beta6) the dependencies on tools.jar and jconsole.jar are vanished.

          I do not made any tests for side effects. At a first glance logging (as far as I use it) seems to work as before.

          Show
          Sebastian Oerding added a comment - Switching to the new version (2.0-beta6) the dependencies on tools.jar and jconsole.jar are vanished. I do not made any tests for side effects. At a first glance logging (as far as I use it) seems to work as before.
          Hide
          Remko Popma added a comment -

          Sebastian,
          For questions, you can either post to one of the mailing lists or create a new JIRA. Both are fine.

          Mailing lists are here: http://logging.apache.org/log4j/2.x/mail-lists.html

          Show
          Remko Popma added a comment - Sebastian, For questions, you can either post to one of the mailing lists or create a new JIRA. Both are fine. Mailing lists are here: http://logging.apache.org/log4j/2.x/mail-lists.html

            People

            • Assignee:
              Remko Popma
              Reporter:
              Sebastian Oerding
            • Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development