Uploaded image for project: 'Log4j 2'
  1. Log4j 2
  2. LOG4J2-1359

Add support for Java 9 StackWalker API in ReflectionUtil

    Details

    • Type: Improvement
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: API
    • Labels:
    • Environment:

      Java 1.9+

      Description

      StackWalker

      Based on the functional nature of this API, supporting it may require compiling at least one class using javac 1.9 and reflectively loading it in ReflectionUtil similar to how Spring supports newer JDK APIs.

      Without support for StackWalker, ReflectionUtil will fall back to using a slower API in Java 1.9. This is because the Reflection class is a sun-internal class which are no longer exported to non-JDK code without setting special command line flags.

        Issue Links

          Activity

          Hide
          remkop@yahoo.com Remko Popma added a comment -

          Interesting. Given the need to compile this with javac 1.9, would this be a separate module then?

          Show
          remkop@yahoo.com Remko Popma added a comment - Interesting. Given the need to compile this with javac 1.9, would this be a separate module then?
          Hide
          ralph.goers@dslextreme.com Ralph Goers added a comment -

          I tested StackWalker a few weeks ago. I don't remember the actual numbers I got, but StackWalker was considerably faster than using a Throwable to capture the location information.

          Show
          ralph.goers@dslextreme.com Ralph Goers added a comment - I tested StackWalker a few weeks ago. I don't remember the actual numbers I got, but StackWalker was considerably faster than using a Throwable to capture the location information.
          Hide
          jvz Matt Sicker added a comment -

          If there's no way to mix the compile environment, then I guess it would have to be in its own jdk9 module, yeah.

          Show
          jvz Matt Sicker added a comment - If there's no way to mix the compile environment, then I guess it would have to be in its own jdk9 module, yeah.
          Hide
          ralph.goers@dslextreme.com Ralph Goers added a comment - - edited

          I need to get back to this...

          Java 9 provides multi-version support - we can provide one version of a class for pre-java9 and another for java9, but it requires the build be done with java 9, which I am reluctant to do.

          Also, the openjdk devs recommend that the stack frame of the caller be captured, not walking the stack as we do now. But that would be a huge change and could negatively impact the performance of every logging call even if logging is disabled.

          Show
          ralph.goers@dslextreme.com Ralph Goers added a comment - - edited I need to get back to this... Java 9 provides multi-version support - we can provide one version of a class for pre-java9 and another for java9, but it requires the build be done with java 9, which I am reluctant to do. Also, the openjdk devs recommend that the stack frame of the caller be captured, not walking the stack as we do now. But that would be a huge change and could negatively impact the performance of every logging call even if logging is disabled.
          Hide
          remkop@yahoo.com Remko Popma added a comment - - edited

          Is it possible to compile only one class with Java 9 and the rest with Java 7? Maybe have a module with Java 9-only functionality?

          We currently delay walking the stack until we need to. Can we do something similar with capturing the stack? That is, only capture it when a) we're logging synchronously and one of the pattern converters asks for the caller location, or b) we're logging asynchronously and we're configured to capture a stack snapshot before handing over the log event details to the background thread?

          I don't understand what the openjdk devs are suggesting concretely. Can you give an example, or point me to something (a specific API, or an example, or an email) that would clarify?

          Show
          remkop@yahoo.com Remko Popma added a comment - - edited Is it possible to compile only one class with Java 9 and the rest with Java 7? Maybe have a module with Java 9-only functionality? We currently delay walking the stack until we need to. Can we do something similar with capturing the stack? That is, only capture it when a) we're logging synchronously and one of the pattern converters asks for the caller location, or b) we're logging asynchronously and we're configured to capture a stack snapshot before handing over the log event details to the background thread? I don't understand what the openjdk devs are suggesting concretely. Can you give an example, or point me to something (a specific API, or an example, or an email) that would clarify?
          Hide
          ralph.goers@dslextreme.com Ralph Goers added a comment -

          Let's see if I can help. First, I suggest you read https://www.sitepoint.com/deep-dive-into-java-9s-stack-walking-api/. Notice that when StackWalker::forEach is used to get the StackTraceElement containing the file name and line number it is actually slower than walking the Throwable, which is in contrast to Reflection.getCallerClass() where we get a performance boost. But also notice that the cost decreases with the number of stack frames that have to be retrieved. So the openjdk devs recommend using StackWalker's getCallerClass method. Of course, the only way to do that is to have the call be in the first Log4j method that is called. Then we would have to pass the retrieved StackFrame instead of the FQCN. IOW, we would not lazily resolve the location information. I have my doubts that can be done without unacceptable performance consequences.

          Worse, I did some gross testing and it seemed that walking the Throwable was slower in Java 9 than in Java 8. However, the openjdk devs believe I did something wrong. The only way to know is to test it. I plan to do just that by starting with https://github.com/pingtimeout/stack-walker-benchmark and then creating a Java 8 version and a Java 9 version.

          So yes, we can defer walking the stack but the cost of retrieving location information will probably be worse than it is pre-Java 9.

          For a reference to the core-libs discussion see the thread that starts with http://mail.openjdk.java.net/pipermail/core-libs-dev/2016-May/040826.html.

          Show
          ralph.goers@dslextreme.com Ralph Goers added a comment - Let's see if I can help. First, I suggest you read https://www.sitepoint.com/deep-dive-into-java-9s-stack-walking-api/ . Notice that when StackWalker::forEach is used to get the StackTraceElement containing the file name and line number it is actually slower than walking the Throwable, which is in contrast to Reflection.getCallerClass() where we get a performance boost. But also notice that the cost decreases with the number of stack frames that have to be retrieved. So the openjdk devs recommend using StackWalker's getCallerClass method. Of course, the only way to do that is to have the call be in the first Log4j method that is called. Then we would have to pass the retrieved StackFrame instead of the FQCN. IOW, we would not lazily resolve the location information. I have my doubts that can be done without unacceptable performance consequences. Worse, I did some gross testing and it seemed that walking the Throwable was slower in Java 9 than in Java 8. However, the openjdk devs believe I did something wrong. The only way to know is to test it. I plan to do just that by starting with https://github.com/pingtimeout/stack-walker-benchmark and then creating a Java 8 version and a Java 9 version. So yes, we can defer walking the stack but the cost of retrieving location information will probably be worse than it is pre-Java 9. For a reference to the core-libs discussion see the thread that starts with http://mail.openjdk.java.net/pipermail/core-libs-dev/2016-May/040826.html .
          Hide
          ralph.goers@dslextreme.com Ralph Goers added a comment - - edited

          I have copied the benchmarks from the sitepoint article and modified them slightly and added benchmarks for java 8. The project is at https://github.com/rgoers/stackwalker-vs-Reflection_getCallerClass. The results on my machine are below. The take-aways are:
          1. Walking the Throwable StackTraceElements is significantly faster in Java 8 than Java 9, so my memory is correct.
          2. Using StackWalker to get the StackTraceElements is almost twice as slow as walking the Throwable in Java 8.
          3. Using StackWalker to search for the caller's class is about twice as slow as sun.reflect.Reflection.getCallerClass() was.
          4. sun.reflect.Reflection.getCallerClass is about 10 times faster than using StackWalker.getCallerClass to obtain the Class object of the immediate caller.

          In short it appears that the performance of StackWalker means that we are going to want to avoid using it.

          Java 8 1.8.0_121:

          Benchmark                                        Mode  Cnt   Score   Error  Units
          ExceptionBenchmark.exceptionStackTrace           avgt   20  19.260 ± 0.385  us/op
          StackWalkerGetCallerClass.exceptionGetImmediate  avgt   20   0.132 ± 0.001  us/op
          StackWalkerGetCallerClass.reflectionSearch       avgt   20   3.703 ± 0.048  us/op
          StackWalkerGetCallerClass.securityManager        avgt   20   0.905 ± 0.007  us/op
          

          Java 9-ea+160:

          Benchmark                                                              (limit)  (skip)  Mode  Cnt   Score   Error  Units
          StackWalkerGetCallerClass.securityManager                                  N/A     N/A  avgt   20   1.554 ± 0.089  us/op
          StackWalkerGetCallerClass.stackwalkerGetImmediate                          N/A     N/A  avgt   20   1.178 ± 0.013  us/op
          StackWalkerGetCallerClass.stackwalkerSearch                                N/A     N/A  avgt   20   5.969 ± 0.055  us/op
          StackWalkerLimitBenchmark.stackWalkerStreamLimit                             1     N/A  avgt   20   2.331 ± 0.015  us/op
          StackWalkerLimitBenchmark.stackWalkerStreamLimit                             2     N/A  avgt   20   2.384 ± 0.017  us/op
          StackWalkerLimitBenchmark.stackWalkerStreamLimit                             4     N/A  avgt   20   2.617 ± 0.021  us/op
          StackWalkerLimitBenchmark.stackWalkerStreamLimit                             6     N/A  avgt   20   2.799 ± 0.025  us/op
          StackWalkerLimitBenchmark.stackWalkerStreamLimit                             8     N/A  avgt   20   7.082 ± 0.056  us/op
          StackWalkerLimitBenchmark.stackWalkerStreamLimit                            10     N/A  avgt   20   7.093 ± 0.122  us/op
          StackWalkerLimitBenchmark.stackWalkerStreamLimit                            12     N/A  avgt   20   7.297 ± 0.039  us/op
          StackWalkerLimitBenchmark.stackWalkerStreamLimit                            14     N/A  avgt   20   7.477 ± 0.061  us/op
          StackWalkerLimitBenchmark.stackWalkerStreamLimit                            16     N/A  avgt   20  11.789 ± 0.079  us/op
          StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit            1     N/A  avgt   20   2.290 ± 0.016  us/op
          StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit            2     N/A  avgt   20   2.253 ± 0.020  us/op
          StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit            4     N/A  avgt   20   2.481 ± 0.082  us/op
          StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit            6     N/A  avgt   20   2.442 ± 0.060  us/op
          StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit            8     N/A  avgt   20   3.151 ± 0.036  us/op
          StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit           10     N/A  avgt   20   3.854 ± 0.040  us/op
          StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit           12     N/A  avgt   20   4.554 ± 0.055  us/op
          StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit           14     N/A  avgt   20   5.139 ± 0.060  us/op
          StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit           16     N/A  avgt   20   5.846 ± 0.085  us/op
          StackWalkerSkipBenchmark.stackWalkerStreamSkip                             N/A       1  avgt   20  12.020 ± 0.087  us/op
          StackWalkerSkipBenchmark.stackWalkerStreamSkip                             N/A       2  avgt   20  11.995 ± 0.061  us/op
          StackWalkerSkipBenchmark.stackWalkerStreamSkip                             N/A       4  avgt   20  12.273 ± 0.180  us/op
          StackWalkerSkipBenchmark.stackWalkerStreamSkip                             N/A       6  avgt   20  12.076 ± 0.122  us/op
          StackWalkerSkipBenchmark.stackWalkerStreamSkip                             N/A       8  avgt   20  12.143 ± 0.130  us/op
          StackWalkerSkipBenchmark.stackWalkerStreamSkip                             N/A      10  avgt   20  12.164 ± 0.133  us/op
          StackWalkerSkipBenchmark.stackWalkerStreamSkip                             N/A      12  avgt   20  12.335 ± 0.280  us/op
          StackWalkerSkipBenchmark.stackWalkerStreamSkip                             N/A      14  avgt   20  11.849 ± 0.070  us/op
          StackWalkerSkipBenchmark.stackWalkerStreamSkip                             N/A      16  avgt   20  11.984 ± 0.145  us/op
          StackWalkerVsExceptionBenchmark.exceptionStackTrace                        N/A     N/A  avgt   20  28.253 ± 0.782  us/op
          StackWalkerVsExceptionBenchmark.stackWalkerForEach                         N/A     N/A  avgt   20  12.084 ± 0.113  us/op
          StackWalkerVsExceptionBenchmark.stackWalkerForEachRetainClass              N/A     N/A  avgt   20  12.093 ± 0.144  us/op
          StackWalkerVsExceptionBenchmark.stackWalkerForEachToStackTraceElement      N/A     N/A  avgt   20  33.717 ± 0.312  us/op
          
          Show
          ralph.goers@dslextreme.com Ralph Goers added a comment - - edited I have copied the benchmarks from the sitepoint article and modified them slightly and added benchmarks for java 8. The project is at https://github.com/rgoers/stackwalker-vs-Reflection_getCallerClass . The results on my machine are below. The take-aways are: 1. Walking the Throwable StackTraceElements is significantly faster in Java 8 than Java 9, so my memory is correct. 2. Using StackWalker to get the StackTraceElements is almost twice as slow as walking the Throwable in Java 8. 3. Using StackWalker to search for the caller's class is about twice as slow as sun.reflect.Reflection.getCallerClass() was. 4. sun.reflect.Reflection.getCallerClass is about 10 times faster than using StackWalker.getCallerClass to obtain the Class object of the immediate caller. In short it appears that the performance of StackWalker means that we are going to want to avoid using it. Java 8 1.8.0_121: Benchmark Mode Cnt Score Error Units ExceptionBenchmark.exceptionStackTrace avgt 20 19.260 ± 0.385 us/op StackWalkerGetCallerClass.exceptionGetImmediate avgt 20 0.132 ± 0.001 us/op StackWalkerGetCallerClass.reflectionSearch avgt 20 3.703 ± 0.048 us/op StackWalkerGetCallerClass.securityManager avgt 20 0.905 ± 0.007 us/op Java 9-ea+160: Benchmark (limit) (skip) Mode Cnt Score Error Units StackWalkerGetCallerClass.securityManager N/A N/A avgt 20 1.554 ± 0.089 us/op StackWalkerGetCallerClass.stackwalkerGetImmediate N/A N/A avgt 20 1.178 ± 0.013 us/op StackWalkerGetCallerClass.stackwalkerSearch N/A N/A avgt 20 5.969 ± 0.055 us/op StackWalkerLimitBenchmark.stackWalkerStreamLimit 1 N/A avgt 20 2.331 ± 0.015 us/op StackWalkerLimitBenchmark.stackWalkerStreamLimit 2 N/A avgt 20 2.384 ± 0.017 us/op StackWalkerLimitBenchmark.stackWalkerStreamLimit 4 N/A avgt 20 2.617 ± 0.021 us/op StackWalkerLimitBenchmark.stackWalkerStreamLimit 6 N/A avgt 20 2.799 ± 0.025 us/op StackWalkerLimitBenchmark.stackWalkerStreamLimit 8 N/A avgt 20 7.082 ± 0.056 us/op StackWalkerLimitBenchmark.stackWalkerStreamLimit 10 N/A avgt 20 7.093 ± 0.122 us/op StackWalkerLimitBenchmark.stackWalkerStreamLimit 12 N/A avgt 20 7.297 ± 0.039 us/op StackWalkerLimitBenchmark.stackWalkerStreamLimit 14 N/A avgt 20 7.477 ± 0.061 us/op StackWalkerLimitBenchmark.stackWalkerStreamLimit 16 N/A avgt 20 11.789 ± 0.079 us/op StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit 1 N/A avgt 20 2.290 ± 0.016 us/op StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit 2 N/A avgt 20 2.253 ± 0.020 us/op StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit 4 N/A avgt 20 2.481 ± 0.082 us/op StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit 6 N/A avgt 20 2.442 ± 0.060 us/op StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit 8 N/A avgt 20 3.151 ± 0.036 us/op StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit 10 N/A avgt 20 3.854 ± 0.040 us/op StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit 12 N/A avgt 20 4.554 ± 0.055 us/op StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit 14 N/A avgt 20 5.139 ± 0.060 us/op StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit 16 N/A avgt 20 5.846 ± 0.085 us/op StackWalkerSkipBenchmark.stackWalkerStreamSkip N/A 1 avgt 20 12.020 ± 0.087 us/op StackWalkerSkipBenchmark.stackWalkerStreamSkip N/A 2 avgt 20 11.995 ± 0.061 us/op StackWalkerSkipBenchmark.stackWalkerStreamSkip N/A 4 avgt 20 12.273 ± 0.180 us/op StackWalkerSkipBenchmark.stackWalkerStreamSkip N/A 6 avgt 20 12.076 ± 0.122 us/op StackWalkerSkipBenchmark.stackWalkerStreamSkip N/A 8 avgt 20 12.143 ± 0.130 us/op StackWalkerSkipBenchmark.stackWalkerStreamSkip N/A 10 avgt 20 12.164 ± 0.133 us/op StackWalkerSkipBenchmark.stackWalkerStreamSkip N/A 12 avgt 20 12.335 ± 0.280 us/op StackWalkerSkipBenchmark.stackWalkerStreamSkip N/A 14 avgt 20 11.849 ± 0.070 us/op StackWalkerSkipBenchmark.stackWalkerStreamSkip N/A 16 avgt 20 11.984 ± 0.145 us/op StackWalkerVsExceptionBenchmark.exceptionStackTrace N/A N/A avgt 20 28.253 ± 0.782 us/op StackWalkerVsExceptionBenchmark.stackWalkerForEach N/A N/A avgt 20 12.084 ± 0.113 us/op StackWalkerVsExceptionBenchmark.stackWalkerForEachRetainClass N/A N/A avgt 20 12.093 ± 0.144 us/op StackWalkerVsExceptionBenchmark.stackWalkerForEachToStackTraceElement N/A N/A avgt 20 33.717 ± 0.312 us/op
          Hide
          jvz Matt Sicker added a comment -

          Well that's no good! Have you posted this to the jdk mailing lists, too? In order to access sun.reflect in Java 9, I think we'll have to add some compilation flags as they're trying to hide all their internal APIs that have public equivalents.

          Show
          jvz Matt Sicker added a comment - Well that's no good! Have you posted this to the jdk mailing lists, too? In order to access sun.reflect in Java 9, I think we'll have to add some compilation flags as they're trying to hide all their internal APIs that have public equivalents.
          Hide
          ralph.goers@dslextreme.com Ralph Goers added a comment -

          Yes, I posted to the open jdk list and referenced this Jira issue and pointed them to my benchmark project. I have not heard anything yet. Of course, it could be possible that there is something wrong with the benchmark code.

          Show
          ralph.goers@dslextreme.com Ralph Goers added a comment - Yes, I posted to the open jdk list and referenced this Jira issue and pointed them to my benchmark project. I have not heard anything yet. Of course, it could be possible that there is something wrong with the benchmark code.
          Hide
          mandy.chung@oracle.com Mandy Chung added a comment -

          See http://mail.openjdk.java.net/pipermail/core-libs-dev/2017-March/046682.html

          Are these benchmarks taking entire stack? StackWalker API improves the performance of the use case when you walk the stack from the most recent execution frame and stops when you reach a certain frame. Also the use case when you want to look at the frame information such as classname/method name or Class object. There is cost to get StackTraceElement is high that could be improved.

          The important thing is to replace the calls to sun.reflect.Reflection.getCallerClass(int) with StackWalker::walk. I would suggest to experiment doing the stack walk from the most recent frame and determine any performance improvement.

          Show
          mandy.chung@oracle.com Mandy Chung added a comment - See http://mail.openjdk.java.net/pipermail/core-libs-dev/2017-March/046682.html Are these benchmarks taking entire stack? StackWalker API improves the performance of the use case when you walk the stack from the most recent execution frame and stops when you reach a certain frame. Also the use case when you want to look at the frame information such as classname/method name or Class object. There is cost to get StackTraceElement is high that could be improved. The important thing is to replace the calls to sun.reflect.Reflection.getCallerClass(int) with StackWalker::walk. I would suggest to experiment doing the stack walk from the most recent frame and determine any performance improvement.
          Hide
          ralph.goers@dslextreme.com Ralph Goers added a comment -

          https://bugs.openjdk.java.net/browse/JDK-8176593 has been created for the performance issue with Throwable.

          I am working on the search performance test as the current method is forced to consume the whole stack. Also, it was recommended to move the creation of the StackWalker out of the test. There was at least one place where this was done in the original tests and I will fix it there as well.

          Show
          ralph.goers@dslextreme.com Ralph Goers added a comment - https://bugs.openjdk.java.net/browse/JDK-8176593 has been created for the performance issue with Throwable. I am working on the search performance test as the current method is forced to consume the whole stack. Also, it was recommended to move the creation of the StackWalker out of the test. There was at least one place where this was done in the original tests and I will fix it there as well.
          Hide
          ralph.goers@dslextreme.com Ralph Goers added a comment -

          I have modified the test that locates the caller class and added a test to locate the caller's StackTraceElement using StackWalker using the same algorithm Log4j uses. The performance of locating the caller's Class is greatly improved from the numbers above and is now faster than using Reflection.getCallerClass(). Locating the caller's StackTraceElement is also much faster with StackWalker than walking the Throwable.

          I should point out that I tried various methods to locate the caller's class and StackTraceElement and finally settled on using the filter method as dropWhile() and reduce() were much slower.

          Benchmark                                                              (limit)  (skip)  Mode  Cnt   Score   Error  Units
          StackWalkerGetCallerClass.securityManager                                  N/A     N/A  avgt   20   1.478 ± 0.013  us/op
          StackWalkerGetCallerClass.stackwalkerGetImmediate                          N/A     N/A  avgt   20   1.185 ± 0.012  us/op
          StackWalkerGetCallerClass.stackwalkerSearch                                N/A     N/A  avgt   20   2.335 ± 0.017  us/op
          StackWalkerLimitBenchmark.stackWalkerStreamLimit                             1     N/A  avgt   20   2.397 ± 0.043  us/op
          StackWalkerLimitBenchmark.stackWalkerStreamLimit                             2     N/A  avgt   20   2.424 ± 0.027  us/op
          StackWalkerLimitBenchmark.stackWalkerStreamLimit                             4     N/A  avgt   20   2.757 ± 0.028  us/op
          StackWalkerLimitBenchmark.stackWalkerStreamLimit                             6     N/A  avgt   20   3.045 ± 0.031  us/op
          StackWalkerLimitBenchmark.stackWalkerStreamLimit                             8     N/A  avgt   20   7.804 ± 0.247  us/op
          StackWalkerLimitBenchmark.stackWalkerStreamLimit                            10     N/A  avgt   20   7.711 ± 0.062  us/op
          StackWalkerLimitBenchmark.stackWalkerStreamLimit                            12     N/A  avgt   20   7.984 ± 0.038  us/op
          StackWalkerLimitBenchmark.stackWalkerStreamLimit                            14     N/A  avgt   20   8.537 ± 0.342  us/op
          StackWalkerLimitBenchmark.stackWalkerStreamLimit                            16     N/A  avgt   20  13.232 ± 0.142  us/op
          StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit            1     N/A  avgt   20   2.640 ± 0.049  us/op
          StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit            2     N/A  avgt   20   2.514 ± 0.014  us/op
          StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit            4     N/A  avgt   20   2.749 ± 0.179  us/op
          StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit            6     N/A  avgt   20   2.627 ± 0.015  us/op
          StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit            8     N/A  avgt   20   3.368 ± 0.028  us/op
          StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit           10     N/A  avgt   20   4.156 ± 0.033  us/op
          StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit           12     N/A  avgt   20   4.857 ± 0.093  us/op
          StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit           14     N/A  avgt   20   5.461 ± 0.065  us/op
          StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit           16     N/A  avgt   20   6.104 ± 0.088  us/op
          StackWalkerSkipBenchmark.stackWalkerStreamSkip                             N/A       1  avgt   20  12.613 ± 0.046  us/op
          StackWalkerSkipBenchmark.stackWalkerStreamSkip                             N/A       2  avgt   20  12.705 ± 0.156  us/op
          StackWalkerSkipBenchmark.stackWalkerStreamSkip                             N/A       4  avgt   20  12.484 ± 0.173  us/op
          StackWalkerSkipBenchmark.stackWalkerStreamSkip                             N/A       6  avgt   20  12.275 ± 0.063  us/op
          StackWalkerSkipBenchmark.stackWalkerStreamSkip                             N/A       8  avgt   20  12.552 ± 0.175  us/op
          StackWalkerSkipBenchmark.stackWalkerStreamSkip                             N/A      10  avgt   20  12.349 ± 0.167  us/op
          StackWalkerSkipBenchmark.stackWalkerStreamSkip                             N/A      12  avgt   20  12.564 ± 0.153  us/op
          StackWalkerSkipBenchmark.stackWalkerStreamSkip                             N/A      14  avgt   20  13.128 ± 0.476  us/op
          StackWalkerSkipBenchmark.stackWalkerStreamSkip                             N/A      16  avgt   20  13.246 ± 0.532  us/op
          StackWalkerVsExceptionBenchmark.exceptionStackTrace                        N/A     N/A  avgt   20  28.558 ± 0.343  us/op
          StackWalkerVsExceptionBenchmark.stackWalkerForEach                         N/A     N/A  avgt   20  12.873 ± 0.171  us/op
          StackWalkerVsExceptionBenchmark.stackWalkerForEachRetainClass              N/A     N/A  avgt   20  12.828 ± 0.236  us/op
          StackWalkerVsExceptionBenchmark.stackWalkerForEachToStackTraceElement      N/A     N/A  avgt   20  35.724 ± 0.123  us/op
          StackWalkerVsExceptionBenchmark.stackwalkerStackTrace                      N/A     N/A  avgt   20   3.763 ± 0.022  us/op
          Show
          ralph.goers@dslextreme.com Ralph Goers added a comment - I have modified the test that locates the caller class and added a test to locate the caller's StackTraceElement using StackWalker using the same algorithm Log4j uses. The performance of locating the caller's Class is greatly improved from the numbers above and is now faster than using Reflection.getCallerClass(). Locating the caller's StackTraceElement is also much faster with StackWalker than walking the Throwable. I should point out that I tried various methods to locate the caller's class and StackTraceElement and finally settled on using the filter method as dropWhile() and reduce() were much slower. Benchmark (limit) (skip) Mode Cnt Score Error Units StackWalkerGetCallerClass.securityManager N/A N/A avgt 20 1.478 ± 0.013 us/op StackWalkerGetCallerClass.stackwalkerGetImmediate N/A N/A avgt 20 1.185 ± 0.012 us/op StackWalkerGetCallerClass.stackwalkerSearch N/A N/A avgt 20 2.335 ± 0.017 us/op StackWalkerLimitBenchmark.stackWalkerStreamLimit 1 N/A avgt 20 2.397 ± 0.043 us/op StackWalkerLimitBenchmark.stackWalkerStreamLimit 2 N/A avgt 20 2.424 ± 0.027 us/op StackWalkerLimitBenchmark.stackWalkerStreamLimit 4 N/A avgt 20 2.757 ± 0.028 us/op StackWalkerLimitBenchmark.stackWalkerStreamLimit 6 N/A avgt 20 3.045 ± 0.031 us/op StackWalkerLimitBenchmark.stackWalkerStreamLimit 8 N/A avgt 20 7.804 ± 0.247 us/op StackWalkerLimitBenchmark.stackWalkerStreamLimit 10 N/A avgt 20 7.711 ± 0.062 us/op StackWalkerLimitBenchmark.stackWalkerStreamLimit 12 N/A avgt 20 7.984 ± 0.038 us/op StackWalkerLimitBenchmark.stackWalkerStreamLimit 14 N/A avgt 20 8.537 ± 0.342 us/op StackWalkerLimitBenchmark.stackWalkerStreamLimit 16 N/A avgt 20 13.232 ± 0.142 us/op StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit 1 N/A avgt 20 2.640 ± 0.049 us/op StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit 2 N/A avgt 20 2.514 ± 0.014 us/op StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit 4 N/A avgt 20 2.749 ± 0.179 us/op StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit 6 N/A avgt 20 2.627 ± 0.015 us/op StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit 8 N/A avgt 20 3.368 ± 0.028 us/op StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit 10 N/A avgt 20 4.156 ± 0.033 us/op StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit 12 N/A avgt 20 4.857 ± 0.093 us/op StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit 14 N/A avgt 20 5.461 ± 0.065 us/op StackWalkerLimitWithEstimatedSizeBenchmark.stackWalkerStreamLimit 16 N/A avgt 20 6.104 ± 0.088 us/op StackWalkerSkipBenchmark.stackWalkerStreamSkip N/A 1 avgt 20 12.613 ± 0.046 us/op StackWalkerSkipBenchmark.stackWalkerStreamSkip N/A 2 avgt 20 12.705 ± 0.156 us/op StackWalkerSkipBenchmark.stackWalkerStreamSkip N/A 4 avgt 20 12.484 ± 0.173 us/op StackWalkerSkipBenchmark.stackWalkerStreamSkip N/A 6 avgt 20 12.275 ± 0.063 us/op StackWalkerSkipBenchmark.stackWalkerStreamSkip N/A 8 avgt 20 12.552 ± 0.175 us/op StackWalkerSkipBenchmark.stackWalkerStreamSkip N/A 10 avgt 20 12.349 ± 0.167 us/op StackWalkerSkipBenchmark.stackWalkerStreamSkip N/A 12 avgt 20 12.564 ± 0.153 us/op StackWalkerSkipBenchmark.stackWalkerStreamSkip N/A 14 avgt 20 13.128 ± 0.476 us/op StackWalkerSkipBenchmark.stackWalkerStreamSkip N/A 16 avgt 20 13.246 ± 0.532 us/op StackWalkerVsExceptionBenchmark.exceptionStackTrace N/A N/A avgt 20 28.558 ± 0.343 us/op StackWalkerVsExceptionBenchmark.stackWalkerForEach N/A N/A avgt 20 12.873 ± 0.171 us/op StackWalkerVsExceptionBenchmark.stackWalkerForEachRetainClass N/A N/A avgt 20 12.828 ± 0.236 us/op StackWalkerVsExceptionBenchmark.stackWalkerForEachToStackTraceElement N/A N/A avgt 20 35.724 ± 0.123 us/op StackWalkerVsExceptionBenchmark.stackwalkerStackTrace N/A N/A avgt 20 3.763 ± 0.022 us/op
          Hide
          jvz Matt Sicker added a comment -

          Is this performance gain only feasible by directly using the StackWalker API in, for example, LogManager and ClassLoaderContextSelector, or does it still perform well when wrapped by ReflectionUtil (and thus requiring an additional stack frame)? If it's the former, then we're going to end up with several classes with Java 9 specific versions in the multi-jar.

          Show
          jvz Matt Sicker added a comment - Is this performance gain only feasible by directly using the StackWalker API in, for example, LogManager and ClassLoaderContextSelector, or does it still perform well when wrapped by ReflectionUtil (and thus requiring an additional stack frame)? If it's the former, then we're going to end up with several classes with Java 9 specific versions in the multi-jar.
          Hide
          ralph.goers@dslextreme.com Ralph Goers added a comment - - edited

          It would be a direct replacement for the method in ReflectionUtil and calcLocation in Log4jLogEvent.

          The MDCFilter benchmark shows that a logging operation that rejects the event based on something in the MDC takes about 50 ns. With stackWalkerGetImmediate taking over 1 ms it would be an intolerable performance hit to add it in AbstractLogger. At roughly 2 ms though, this isn't much of an impact if you are logging to a file or a socket.

          Show
          ralph.goers@dslextreme.com Ralph Goers added a comment - - edited It would be a direct replacement for the method in ReflectionUtil and calcLocation in Log4jLogEvent. The MDCFilter benchmark shows that a logging operation that rejects the event based on something in the MDC takes about 50 ns. With stackWalkerGetImmediate taking over 1 ms it would be an intolerable performance hit to add it in AbstractLogger. At roughly 2 ms though, this isn't much of an impact if you are logging to a file or a socket.
          Hide
          jira-bot ASF subversion and git services added a comment -

          Commit 0854d32523cc2f244a0ed9a927154dadfbf9534e in logging-log4j2's branch refs/heads/LOG4J2-1359 from Ralph Goers
          [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=0854d32 ]

          LOG4J2-1359 - Java 9 support

          Show
          jira-bot ASF subversion and git services added a comment - Commit 0854d32523cc2f244a0ed9a927154dadfbf9534e in logging-log4j2's branch refs/heads/ LOG4J2-1359 from Ralph Goers [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=0854d32 ] LOG4J2-1359 - Java 9 support
          Hide
          jira-bot ASF subversion and git services added a comment -

          Commit 4e44466fddb33da1835d82f44a538277741b9156 in logging-log4j2's branch refs/heads/LOG4J2-1359 from Ralph Goers
          [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=4e44466 ]

          LOG4J2-1359 - Remove profiles

          Show
          jira-bot ASF subversion and git services added a comment - Commit 4e44466fddb33da1835d82f44a538277741b9156 in logging-log4j2's branch refs/heads/ LOG4J2-1359 from Ralph Goers [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=4e44466 ] LOG4J2-1359 - Remove profiles
          Hide
          jira-bot ASF subversion and git services added a comment -

          Commit e6ce8e4e137f00e9c3ab2f341dfda03c1f76a88a in logging-log4j2's branch refs/heads/LOG4J2-1359 from Ralph Goers
          [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=e6ce8e4 ]

          LOG4J2-1359 - Ignore javadoc problems in core due to Java 9 classes. Modify build instructions

          Show
          jira-bot ASF subversion and git services added a comment - Commit e6ce8e4e137f00e9c3ab2f341dfda03c1f76a88a in logging-log4j2's branch refs/heads/ LOG4J2-1359 from Ralph Goers [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=e6ce8e4 ] LOG4J2-1359 - Ignore javadoc problems in core due to Java 9 classes. Modify build instructions
          Hide
          ralph.goers@dslextreme.com Ralph Goers added a comment - - edited

          I have created branch LOG4J2-1359. To build Log4j you must install Java 9 and create a toolchains.xml that points to it.

          I have created a Jenkins job that verifies the build works in Jenkins (obviously). The only thing I don't like is that the toolchains.xml file has to be updated to point to the latest java 9 install. For some reason there is no symlink.

          I still have to do some performance testing, but please take a look.

          Show
          ralph.goers@dslextreme.com Ralph Goers added a comment - - edited I have created branch LOG4J2-1359 . To build Log4j you must install Java 9 and create a toolchains.xml that points to it. I have created a Jenkins job that verifies the build works in Jenkins (obviously). The only thing I don't like is that the toolchains.xml file has to be updated to point to the latest java 9 install. For some reason there is no symlink. I still have to do some performance testing, but please take a look.
          Hide
          jira-bot ASF subversion and git services added a comment -

          Commit 8eac91024cce617b15838c1f630d8aa32703c6f3 in logging-log4j2's branch refs/heads/LOG4J2-1359 from Ralph Goers
          [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=8eac910 ]

          LOG4J2-1359 - Benchmark impact on LogEvent

          Show
          jira-bot ASF subversion and git services added a comment - Commit 8eac91024cce617b15838c1f630d8aa32703c6f3 in logging-log4j2's branch refs/heads/ LOG4J2-1359 from Ralph Goers [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=8eac910 ] LOG4J2-1359 - Benchmark impact on LogEvent
          Hide
          ralph.goers@dslextreme.com Ralph Goers added a comment - - edited

          Here are the results of the benchmarks. Overall, it seems that most of the tests are a bit slower in Java 9. Serializing an Event that has an Exception is a LOT slower, which is probably a result of the performance regression I already reported. However, getting the location information takes about 1/3 the time it did in Java 7.

          I don't understand the results of the serialization tests though. Although it is understandable that building a log event without an exception would be much faster than building one with one, I would have expected that building a serialized log event with location information would be about the same as building an event without location information + the time to get the location information. Instead, in Java 9 it is showing as slightly faster than getting the event without location information. I am thinking there must be something wrong with the test.

          Java 7

          Benchmark                                                                                         Mode  Samples      Score      Error  Units
          o.a.l.l.p.j.Log4jLogEventBenchmark.createLogEventWithExceptionUsingBuilder                        avgt        5    147.173 ±    3.876  ns/op
          o.a.l.l.p.j.Log4jLogEventBenchmark.createLogEventWithoutException                                 avgt        5    177.807 ±   18.619  ns/op
          o.a.l.l.p.j.Log4jLogEventBenchmark.createLogEventWithoutExceptionUsingBuilder                     avgt        5    146.371 ±    9.554  ns/op
          o.a.l.l.p.j.Log4jLogEventBenchmark.createSerializableLogEventProxyWithException                   avgt        5  18450.541 ±  380.800  ns/op
          o.a.l.l.p.j.Log4jLogEventBenchmark.createSerializableLogEventProxyWithoutException                avgt        5    250.715 ±    8.624  ns/op
          o.a.l.l.p.j.Log4jLogEventBenchmark.createSerializableLogEventProxyWithoutExceptionWithLocation    avgt        5    274.293 ±   35.927  ns/op
          o.a.l.l.p.j.Log4jLogEventBenchmark.getSourceLocationOfLogEvent                                    avgt        5  19988.446 ± 1752.194  ns/op
          o.a.l.l.p.j.Log4jLogEventBenchmark.testBaseline                                                   avgt        5      0.391 ±    0.028  ns/op
          

          Java 9

          Benchmark                                                                                         Mode  Samples      Score      Error  Units
          o.a.l.l.p.j.Log4jLogEventBenchmark.createLogEventWithExceptionUsingBuilder                        avgt        5    190.018 ±   28.264  ns/op
          o.a.l.l.p.j.Log4jLogEventBenchmark.createLogEventWithoutException                                 avgt        5    228.393 ±   16.702  ns/op
          o.a.l.l.p.j.Log4jLogEventBenchmark.createLogEventWithoutExceptionUsingBuilder                     avgt        5    171.760 ±   26.799  ns/op
          o.a.l.l.p.j.Log4jLogEventBenchmark.createSerializableLogEventProxyWithException                   avgt        5  32257.972 ± 4868.261  ns/op
          o.a.l.l.p.j.Log4jLogEventBenchmark.createSerializableLogEventProxyWithoutException                avgt        5    285.204 ±   20.197  ns/op
          o.a.l.l.p.j.Log4jLogEventBenchmark.createSerializableLogEventProxyWithoutExceptionWithLocation    avgt        5    271.399 ±   28.883  ns/op
          o.a.l.l.p.j.Log4jLogEventBenchmark.getSourceLocationOfLogEvent                                    avgt        5   6839.420 ± 1007.405  ns/op
          o.a.l.l.p.j.Log4jLogEventBenchmark.testBaseline                                                   avgt        5      0.402 ±    0.009  ns/op
          
          Show
          ralph.goers@dslextreme.com Ralph Goers added a comment - - edited Here are the results of the benchmarks. Overall, it seems that most of the tests are a bit slower in Java 9. Serializing an Event that has an Exception is a LOT slower, which is probably a result of the performance regression I already reported. However, getting the location information takes about 1/3 the time it did in Java 7. I don't understand the results of the serialization tests though. Although it is understandable that building a log event without an exception would be much faster than building one with one, I would have expected that building a serialized log event with location information would be about the same as building an event without location information + the time to get the location information. Instead, in Java 9 it is showing as slightly faster than getting the event without location information. I am thinking there must be something wrong with the test. Java 7 Benchmark Mode Samples Score Error Units o.a.l.l.p.j.Log4jLogEventBenchmark.createLogEventWithExceptionUsingBuilder avgt 5 147.173 ± 3.876 ns/op o.a.l.l.p.j.Log4jLogEventBenchmark.createLogEventWithoutException avgt 5 177.807 ± 18.619 ns/op o.a.l.l.p.j.Log4jLogEventBenchmark.createLogEventWithoutExceptionUsingBuilder avgt 5 146.371 ± 9.554 ns/op o.a.l.l.p.j.Log4jLogEventBenchmark.createSerializableLogEventProxyWithException avgt 5 18450.541 ± 380.800 ns/op o.a.l.l.p.j.Log4jLogEventBenchmark.createSerializableLogEventProxyWithoutException avgt 5 250.715 ± 8.624 ns/op o.a.l.l.p.j.Log4jLogEventBenchmark.createSerializableLogEventProxyWithoutExceptionWithLocation avgt 5 274.293 ± 35.927 ns/op o.a.l.l.p.j.Log4jLogEventBenchmark.getSourceLocationOfLogEvent avgt 5 19988.446 ± 1752.194 ns/op o.a.l.l.p.j.Log4jLogEventBenchmark.testBaseline avgt 5 0.391 ± 0.028 ns/op Java 9 Benchmark Mode Samples Score Error Units o.a.l.l.p.j.Log4jLogEventBenchmark.createLogEventWithExceptionUsingBuilder avgt 5 190.018 ± 28.264 ns/op o.a.l.l.p.j.Log4jLogEventBenchmark.createLogEventWithoutException avgt 5 228.393 ± 16.702 ns/op o.a.l.l.p.j.Log4jLogEventBenchmark.createLogEventWithoutExceptionUsingBuilder avgt 5 171.760 ± 26.799 ns/op o.a.l.l.p.j.Log4jLogEventBenchmark.createSerializableLogEventProxyWithException avgt 5 32257.972 ± 4868.261 ns/op o.a.l.l.p.j.Log4jLogEventBenchmark.createSerializableLogEventProxyWithoutException avgt 5 285.204 ± 20.197 ns/op o.a.l.l.p.j.Log4jLogEventBenchmark.createSerializableLogEventProxyWithoutExceptionWithLocation avgt 5 271.399 ± 28.883 ns/op o.a.l.l.p.j.Log4jLogEventBenchmark.getSourceLocationOfLogEvent avgt 5 6839.420 ± 1007.405 ns/op o.a.l.l.p.j.Log4jLogEventBenchmark.testBaseline avgt 5 0.402 ± 0.009 ns/op
          Hide
          jira-bot ASF subversion and git services added a comment -

          Commit 311101cb47594a4bc781a5365a471d5be7f40647 in logging-log4j2's branch refs/heads/LOG4J2-1359 from Ralph Goers
          [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=311101c ]

          LOG4J2-1359 - Remove print statement

          Show
          jira-bot ASF subversion and git services added a comment - Commit 311101cb47594a4bc781a5365a471d5be7f40647 in logging-log4j2's branch refs/heads/ LOG4J2-1359 from Ralph Goers [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=311101c ] LOG4J2-1359 - Remove print statement
          Hide
          ralph.goers@dslextreme.com Ralph Goers added a comment -

          In the issue for the Maven bundle plugin it was suggested we use a "service" for the replaceable functionality, which I take to mean that the ServiceLoader should be used. I'll have to dwell on the issues in doing that.

          Show
          ralph.goers@dslextreme.com Ralph Goers added a comment - In the issue for the Maven bundle plugin it was suggested we use a "service" for the replaceable functionality, which I take to mean that the ServiceLoader should be used. I'll have to dwell on the issues in doing that.
          Hide
          jira-bot ASF subversion and git services added a comment -

          Commit 34552d7d725c3b7547e1c19f6ce803b83c60bd94 in logging-log4j2's branch refs/heads/java9NoMultiRelease from Ralph Goers
          [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=34552d7 ]

          LOG4J2-1359 - Set up for modules. Do not use multi-release jars

          Show
          jira-bot ASF subversion and git services added a comment - Commit 34552d7d725c3b7547e1c19f6ce803b83c60bd94 in logging-log4j2's branch refs/heads/java9NoMultiRelease from Ralph Goers [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=34552d7 ] LOG4J2-1359 - Set up for modules. Do not use multi-release jars
          Hide
          jira-bot ASF subversion and git services added a comment -

          Commit 0854d32523cc2f244a0ed9a927154dadfbf9534e in logging-log4j2's branch refs/heads/master from Ralph Goers
          [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=0854d32 ]

          LOG4J2-1359 - Java 9 support

          Show
          jira-bot ASF subversion and git services added a comment - Commit 0854d32523cc2f244a0ed9a927154dadfbf9534e in logging-log4j2's branch refs/heads/master from Ralph Goers [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=0854d32 ] LOG4J2-1359 - Java 9 support
          Hide
          jira-bot ASF subversion and git services added a comment -

          Commit e6ce8e4e137f00e9c3ab2f341dfda03c1f76a88a in logging-log4j2's branch refs/heads/master from Ralph Goers
          [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=e6ce8e4 ]

          LOG4J2-1359 - Ignore javadoc problems in core due to Java 9 classes. Modify build instructions

          Show
          jira-bot ASF subversion and git services added a comment - Commit e6ce8e4e137f00e9c3ab2f341dfda03c1f76a88a in logging-log4j2's branch refs/heads/master from Ralph Goers [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=e6ce8e4 ] LOG4J2-1359 - Ignore javadoc problems in core due to Java 9 classes. Modify build instructions
          Hide
          jira-bot ASF subversion and git services added a comment -

          Commit 8eac91024cce617b15838c1f630d8aa32703c6f3 in logging-log4j2's branch refs/heads/master from Ralph Goers
          [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=8eac910 ]

          LOG4J2-1359 - Benchmark impact on LogEvent

          Show
          jira-bot ASF subversion and git services added a comment - Commit 8eac91024cce617b15838c1f630d8aa32703c6f3 in logging-log4j2's branch refs/heads/master from Ralph Goers [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=8eac910 ] LOG4J2-1359 - Benchmark impact on LogEvent
          Hide
          jira-bot ASF subversion and git services added a comment -

          Commit 311101cb47594a4bc781a5365a471d5be7f40647 in logging-log4j2's branch refs/heads/master from Ralph Goers
          [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=311101c ]

          LOG4J2-1359 - Remove print statement

          Show
          jira-bot ASF subversion and git services added a comment - Commit 311101cb47594a4bc781a5365a471d5be7f40647 in logging-log4j2's branch refs/heads/master from Ralph Goers [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=311101c ] LOG4J2-1359 - Remove print statement
          Hide
          jira-bot ASF subversion and git services added a comment -

          Commit 34552d7d725c3b7547e1c19f6ce803b83c60bd94 in logging-log4j2's branch refs/heads/master from Ralph Goers
          [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=34552d7 ]

          LOG4J2-1359 - Set up for modules. Do not use multi-release jars

          Show
          jira-bot ASF subversion and git services added a comment - Commit 34552d7d725c3b7547e1c19f6ce803b83c60bd94 in logging-log4j2's branch refs/heads/master from Ralph Goers [ https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=34552d7 ] LOG4J2-1359 - Set up for modules. Do not use multi-release jars
          Hide
          ralph.goers@dslextreme.com Ralph Goers added a comment -

          This has now been pushed to master.

          Show
          ralph.goers@dslextreme.com Ralph Goers added a comment - This has now been pushed to master.
          Hide
          ralph.goers@dslextreme.com Ralph Goers added a comment -

          Please verify and close.

          Show
          ralph.goers@dslextreme.com Ralph Goers added a comment - Please verify and close.
          Hide
          vy Volkan Yazıcı added a comment -

          Hey Ralph Goers, since the source code version is set to Java 1.7 according pom.xml, lambdas in StackWalkerStackLocator break the IDE (IntelliJ IDEA) build. (I expect more classes.) It feels like it was a little bit earlier to merge this into master without bumping the Maven source code versions. How can I circumvent this problem?

          Show
          vy Volkan Yazıcı added a comment - Hey Ralph Goers , since the source code version is set to Java 1.7 according pom.xml, lambdas in StackWalkerStackLocator break the IDE (IntelliJ IDEA) build. (I expect more classes.) It feels like it was a little bit earlier to merge this into master without bumping the Maven source code versions. How can I circumvent this problem?
          Hide
          ralph.goers@dslextreme.com Ralph Goers added a comment -

          Please see the instructions in src/site/markdown/build.md and in BUILDING.md. master requires both Java 9 and Java 7 to build.

          Show
          ralph.goers@dslextreme.com Ralph Goers added a comment - Please see the instructions in src/site/markdown/build.md and in BUILDING.md. master requires both Java 9 and Java 7 to build.
          Hide
          mikaelstaldal Mikael Ståldal added a comment -

          Those instructions only tell you how to perform the Maven build, not how to setup the project in IDEs like IntelliJ IDEA and Eclipse.

          Show
          mikaelstaldal Mikael Ståldal added a comment - Those instructions only tell you how to perform the Maven build, not how to setup the project in IDEs like IntelliJ IDEA and Eclipse.
          Hide
          ralph.goers@dslextreme.com Ralph Goers added a comment -

          I suppose that's true. I have never built Log4j in IntelliJ or Eclipse so how to build it there has never been documented.

          Show
          ralph.goers@dslextreme.com Ralph Goers added a comment - I suppose that's true. I have never built Log4j in IntelliJ or Eclipse so how to build it there has never been documented.
          Hide
          vy Volkan Yazıcı added a comment -

          May I ask how do other people work on the project? Am I the only one who wants to take advantage of the warm comforting feeling of an IDE?

          Show
          vy Volkan Yazıcı added a comment - May I ask how do other people work on the project? Am I the only one who wants to take advantage of the warm comforting feeling of an IDE?
          Hide
          mikaelstaldal Mikael Ståldal added a comment -

          I don't use an IDE to build the project for the purpose of producing artifacts, I don't think that's an important use case to be supported.

          However, I do always use an IDE (IntelliJ IDEA) for development, and for that purpose it is important that the IDE is able to compile the project, and also run unit tests. I think that's an important use case.

          After addition of the Java 9 stuff, I had to make some manual tweaks to the the project in IntelliJ IDEA, and I still haven't got it to work perfectly (although good enough to be usable).

          See this thread in mailing list: https://lists.apache.org/list.html?dev@logging.apache.org:lte=6M:%22Java%209%20support%20has%22

          Show
          mikaelstaldal Mikael Ståldal added a comment - I don't use an IDE to build the project for the purpose of producing artifacts, I don't think that's an important use case to be supported. However, I do always use an IDE (IntelliJ IDEA) for development, and for that purpose it is important that the IDE is able to compile the project, and also run unit tests. I think that's an important use case. After addition of the Java 9 stuff, I had to make some manual tweaks to the the project in IntelliJ IDEA, and I still haven't got it to work perfectly (although good enough to be usable). See this thread in mailing list: https://lists.apache.org/list.html?dev@logging.apache.org:lte=6M:%22Java%209%20support%20has%22
          Hide
          jvz Matt Sicker added a comment -

          The only build hack I know of (which is irritating but not too big a deal) is running "mvn install" first before being able to run unit tests from IntelliJ due to a missing annotation processor error (which becomes available from a daily snapshot after running install).

          Show
          jvz Matt Sicker added a comment - The only build hack I know of (which is irritating but not too big a deal) is running "mvn install" first before being able to run unit tests from IntelliJ due to a missing annotation processor error (which becomes available from a daily snapshot after running install).
          Hide
          garydgregory Gary Gregory added a comment -

          Doing anything in Eclipse is currently near impossible FWIW. Even with the Java 9 beta support installed.

          Show
          garydgregory Gary Gregory added a comment - Doing anything in Eclipse is currently near impossible FWIW. Even with the Java 9 beta support installed.

            People

            • Assignee:
              ralph.goers@dslextreme.com Ralph Goers
              Reporter:
              jvz Matt Sicker
            • Votes:
              0 Vote for this issue
              Watchers:
              8 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development