Apache Sirona and Java 8


Java 8 went out few weeks ago and the question of monitoring is already here. Apache Sirona has several monitoring/interception flavors like CDI, Spring, JavaAgent…but the most interesting is the javaagent which doesn’t mandate to be integrated with a particular technology.

Since it instruments bytecode the question of Java 8 compatibility is important.

Since last week Sirona javaagent now uses asm 5 which supports Java 8. Another important thing is the javaagent was rewritten to really instrument in place methods and not create a kind of proxy. What does it change?

Well first asm upgrade allows you to use Java 8 with Sirona which is already important.

Then if you write a little Java 8 application, let say this one:

package org.foo;

// some imports

public class SironaTest {
    @Test
    public void run() {
        assertEquals("foo", new Simple().name());
        assertEquals("default name", new DefaultImpl().defaultName());
        assertEquals("default name", new DefaultImpl2().defaultName());

        dump();
    }

    private void dump() { // dump sirona information playing with java 8
        final List<Counter> c = new ArrayList<>(Repository.INSTANCE.counters());
        System.out.println("#Counters = " + c.size());
        c.stream()
            .filter(c1 ->
                    !c1.getKey().getName().startsWith("com.intellij")
                && !c1.getKey().getName().startsWith("org.junit")
                && !c1.getKey().getName().startsWith("jdk.")
                && !c1.getKey().getName().startsWith("junit"))
            .sorted((c1, c2) -> c1.getKey().getName().compareTo(c2.getKey().getName()))
            .forEach(System.out::println);
    }

    public static class Simple {
        String name() {
            // to check we support lambda in enhanced classes
            return asList("foo", "bar").stream()
                    .filter(c1 -> !c1.startsWith("b"))
                    .reduce((a, b) -> a + b)
                    .get();
        }
    }

    public static class DefaultImpl implements DefaultItf {

    }

    public static interface DefaultItf {
        default String defaultName() {
            return "default name";
        }
    }
}

And if you add sirona javaagent on the test JVM you’ll get a lot of information and the interesting ones are:

DefaultCounter{concurrency=0, key=name=org.foo.SironaTest$DefaultImpl2.defaultName, dataStore=org.apache.sirona.store.counter.InMemoryCounterDataStore@763d9750, maxConcurrency=1, statistics=OptimizedStatistics{n=1, sum=19377.0, min=19377.0, max=19377.0, m1=19377.0, m2=0.0}}
DefaultCounter{concurrency=0, key=name=org.foo.SironaTest$DefaultItf.defaultName, dataStore=org.apache.sirona.store.counter.InMemoryCounterDataStore@763d9750, maxConcurrency=1, statistics=OptimizedStatistics{n=2, sum=10669.0, min=2070.0, max=8599.0, m1=5334.5, m2=2.13139205E7}}
DefaultCounter{concurrency=0, key=name=org.foo.SironaTest$Simple.lambda$name$3, dataStore=org.apache.sirona.store.counter.InMemoryCounterDataStore@763d9750, maxConcurrency=1, statistics=OptimizedStatistics{n=2, sum=42366.0, min=2109.0, max=40257.0, m1=21183.0, m2=7.27634952E8}}
DefaultCounter{concurrency=0, key=name=org.foo.SironaTest$Simple.name, dataStore=org.apache.sirona.store.counter.InMemoryCounterDataStore@763d9750, maxConcurrency=1, statistics=OptimizedStatistics{n=1, sum=2.11358741E8, min=2.11358741E8, max=2.11358741E8, m1=2.11358741E8, m2=0.0}}
DefaultCounter{concurrency=1, key=name=org.foo.SironaTest.dump, dataStore=org.apache.sirona.store.counter.InMemoryCounterDataStore@763d9750, maxConcurrency=1, statistics=OptimizedStatistics{n=0, sum=0.0, min=NaN, max=NaN, m1=NaN, m2=NaN}}
DefaultCounter{concurrency=1, key=name=org.foo.SironaTest.run, dataStore=org.apache.sirona.store.counter.InMemoryCounterDataStore@763d9750, maxConcurrency=1, statistics=OptimizedStatistics{n=0, sum=0.0, min=NaN, max=NaN, m1=NaN, m2=NaN}}

If we clean up it a bit we get:

key=name=org.foo.SironaTest$DefaultImpl2.defaultName
key=name=org.foo.SironaTest$DefaultItf.defaultName
key=name=org.foo.SironaTest$Simple.lambda$name$3
key=name=org.foo.SironaTest$Simple.name

What we can see is:

  • Sirona intercepts well java 8 methods
  • Sirona intercepts well java 8 default interface methods 🙂 (here DefaultItf.defaultName())
  • Sirona intercepts well java 8 lambdas 🙂 (here Simple.name() lambda seen as Simple.lambda$name$3)

So sirona is ready Java 8 so really no reason to not monitor your apps 😉

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s