{"action":"created","issue":{"url":"https://api.github.com/repos/jboss-javassist/javassist/issues/71","repository_url":"https://api.github.com/repos/jboss-javassist/javassist","labels_url":"https://api.github.com/repos/jboss-javassist/javassist/issues/71/labels{/name}","comments_url":"https://api.github.com/repos/jboss-javassist/javassist/issues/71/comments","events_url":"https://api.github.com/repos/jboss-javassist/javassist/issues/71/events","html_url":"https://github.com/jboss-javassist/javassist/issues/71","id":140965040,"number":71,"title":"java.lang.ExceptionInInitializerError when instrumenting the constructor of an inner class","user":{"login":"jose","id":763676,"avatar_url":"https://avatars.githubusercontent.com/u/763676?v=3","gravatar_id":"","url":"https://api.github.com/users/jose","html_url":"https://github.com/jose","followers_url":"https://api.github.com/users/jose/followers","following_url":"https://api.github.com/users/jose/following{/other_user}","gists_url":"https://api.github.com/users/jose/gists{/gist_id}","starred_url":"https://api.github.com/users/jose/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jose/subscriptions","organizations_url":"https://api.github.com/users/jose/orgs","repos_url":"https://api.github.com/users/jose/repos","events_url":"https://api.github.com/users/jose/events{/privacy}","received_events_url":"https://api.github.com/users/jose/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2016-03-15T13:00:24Z","updated_at":"2016-03-15T16:07:46Z","closed_at":null,"body":"Hi,\r\n\r\nI've been working on a library that reports the line coverage of unit test cases, and it uses Javassist to instrument the java code. It works pretty well, actually Javassist API is very easy to use (thanks for that), but there is a weird case that leads to a `java.lang.ExceptionInInitializerError`. Let suppose that I'm trying to get the coverage of the following class:\r\n```\r\n\r\npublic abstract class Foo {\r\n\r\n  public static final ExtendsFoo extendsFoo = new ExtendsFoo();\r\n\r\n  protected Foo() {\r\n    super();\r\n  }\r\n\r\n  public static class ExtendsFoo extends Foo {\r\n    public ExtendsFoo() {\r\n      super();\r\n    }\r\n  }\r\n}\r\n```\r\nusing the following test case:\r\n```\r\n\r\nimport static org.junit.Assert.assertNotNull;\r\nimport org.junit.Test;\r\n\r\npublic class TestFoo {\r\n\r\n  @Test\r\n  public void test() {\r\n    Foo.ExtendsFoo other_foo = new Foo.ExtendsFoo();\r\n    assertNotNull(other_foo);\r\n  }\r\n}\r\n```\r\nafter instrument the class under test, I got the following bytecode\r\n```\r\npublic abstract class Foo {\r\n  public static final Foo$ExtendsFoo extendsFoo;\r\n\r\n  public static final int[] $__my_field;\r\n\r\n  protected Foo();\r\n    Code:\r\n       0: getstatic     #26                 // Field $__my_field:[I\r\n       3: iconst_0      \r\n       4: dup2          \r\n       5: iaload        \r\n       6: iconst_1      \r\n       7: iadd          \r\n       8: iastore       \r\n       9: aload_0       \r\n      10: invokespecial #1                  // Method java/lang/Object.\"<init>\":()V\r\n      13: getstatic     #26                 // Field $__my_field:[I\r\n      16: iconst_1      \r\n      17: dup2          \r\n      18: iaload        \r\n      19: iconst_1      \r\n      20: iadd          \r\n      21: iastore       \r\n      22: return        \r\n    LineNumberTable:\r\n      line 7: 0\r\n      line 8: 13\r\n\r\n  static {};\r\n    Code:\r\n       0: iconst_2      \r\n       1: newarray       int\r\n       3: putstatic     #26                 // Field $__my_field:[I\r\n       6: new           #2                  // class Foo$ExtendsFoo\r\n       9: dup           \r\n      10: invokespecial #3                  // Method Foo$ExtendsFoo.\"<init>\":()V\r\n      13: putstatic     #4                  // Field extendsFoo:LFoo$ExtendsFoo;\r\n      16: return        \r\n    LineNumberTable:\r\n      line 4: 6\r\n}\r\n\r\npublic class Foo$ExtendsFoo extends Foo {\r\n  public static final int[] $__my_field;\r\n\r\n  public Foo$ExtendsFoo();\r\n    Code:\r\n       0: getstatic     #18                 // Field $__my_field:[I\r\n       3: iconst_0      \r\n       4: dup2          \r\n       5: iaload        \r\n       6: iconst_1      \r\n       7: iadd          \r\n       8: iastore       \r\n       9: aload_0       \r\n      10: invokespecial #1                  // Method Foo.\"<init>\":()V\r\n      13: getstatic     #18                 // Field $__my_field:[I\r\n      16: iconst_1      \r\n      17: dup2          \r\n      18: iaload        \r\n      19: iconst_1      \r\n      20: iadd          \r\n      21: iastore       \r\n      22: return        \r\n    LineNumberTable:\r\n      line 12: 0\r\n      line 13: 13\r\n\r\n  static {};\r\n    Code:\r\n       0: iconst_2      \r\n       1: newarray       int\r\n       3: putstatic     #18                 // Field $__my_field:[I\r\n       6: return        \r\n}\r\n```\r\nand, when I run the test case (using for example JUnit command line) on the instrumented code, I got the following exception:\r\n```\r\njava.lang.ExceptionInInitializerError\r\n\tat TestFoo.test(TestFoo.java:9)\r\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)\r\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n\tat java.lang.reflect.Method.invoke(Method.java:606)\r\n        ...\r\nCaused by: java.lang.NullPointerException\r\n\tat Foo$ExtendsFoo.<init>(Foo.java:12)\r\n\tat Foo.<clinit>(Foo.java:4)\r\n```\r\n\r\nit seems that the JVM tries to create a new instance of `Foo`, which creates a new instance of `ExtendsFoo` in the static constructor, and the exception occurs. if I don't instrument the constructor of `ExtendsFoo` class, the `java.lang.ExceptionInInitializerError` isn't thrown and the test case returns success.\r\n\r\nam I doing something really wrong? or, is this a Javassist issue?\r\n\r\n\r\n--\r\nThanks"},"comment":{"url":"https://api.github.com/repos/jboss-javassist/javassist/issues/comments/196899752","html_url":"https://github.com/jboss-javassist/javassist/issues/71#issuecomment-196899752","issue_url":"https://api.github.com/repos/jboss-javassist/javassist/issues/71","id":196899752,"user":{"login":"chibash","id":4458811,"avatar_url":"https://avatars.githubusercontent.com/u/4458811?v=3","gravatar_id":"","url":"https://api.github.com/users/chibash","html_url":"https://github.com/chibash","followers_url":"https://api.github.com/users/chibash/followers","following_url":"https://api.github.com/users/chibash/following{/other_user}","gists_url":"https://api.github.com/users/chibash/gists{/gist_id}","starred_url":"https://api.github.com/users/chibash/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chibash/subscriptions","organizations_url":"https://api.github.com/users/chibash/orgs","repos_url":"https://api.github.com/users/chibash/repos","events_url":"https://api.github.com/users/chibash/events{/privacy}","received_events_url":"https://api.github.com/users/chibash/received_events","type":"User","site_admin":false},"created_at":"2016-03-15T16:07:46Z","updated_at":"2016-03-15T16:07:46Z","body":"Yes, I think that's a good solution."}}