2016-08-04 1 views
0

私の個人用プロジェクトのJavaエージェントで作業していて、本当に特異なエラーが発生しました。私のIDEにの "register"メソッドを実行すると問題なく動作します。円形度エラーはありません。しかし、エージェントをエクスポートして起動引数で使用すると、javaagent:"agent.jar"がクラッシュし、ClassCircularityError (ループスーパークラス階層)が返されます。スーパークラス階層が正常な場合のClassCircularityError

public class Refactorer implements ClassFileTransformer { 
    private static final Set<AbstractMatcher<String>> matchers = new HashSet<AbstractMatcher<String>>(); 

    public static void register(AbstractMatcher<String> matcher) { 
     matchers.add(matcher); 
    } 

    public byte[] transform(ClassLoader loader, String name, Class<?> clazz, ProtectionDomain domain, byte[] bytes) throws IllegalClassFormatException {} 
} 

STACKTRACE

java.lang.reflect.InvocationTargetException 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:386) 
    at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:401) 
Caused by: java.lang.ClassCircularityError: java/util/Set 
    at me.vader.Refactorer.register(Refactorer.java:42) 
    at me.vader.Setup.registerModders(Setup.java:30) 
    at me.vader.Agent.setAndAddTransformer(Agent.java:37) 
    at me.vader.Agent.premain(Agent.java:18) 

本当に私を混乱させています私はコンパイルエージェントでスーパークラス階層をチェックすると、それは罰金をプリントアウトしていることです。

// The "matchers" 
Class (Sup x0): java.util.HashSet 
Class (Sup x1): java.util.AbstractSet 
Class (Sup x2): java.util.AbstractCollection 
Class (Sup x3): java.lang.Object 

// The matcher being added to "matchers" 
Class (Sup x0): me.vader.match.ClassMatcher 
Class (Sup x1): me.vader.match.AbstractMatcher 
Class (Sup x2): java.lang.Object 

答えて

0

クラスが正しい順序でロードされていなかったようだ:出力

Class c = matchers.getClass(); 
int i = 0; 
while (c != null){ 
    System.out.println("Class (Sup x" + i+ "): " + c.getName()); 
    c = c.getSuperclass(); 
    i++; 
} 

i = 0; 
c = matcher.getClass(); 
while (c != null){ 
    System.out.println("Class (Sup x" + i+ "): " + c.getName()); 
    c = c.getSuperclass(); 
    i++; 
} 

はでテストされています。なぜか分からないけど、それはそうだ。

私の修正はRefactorerクラスでfolllowing叩きされています。それらを強制

static { 
    Serializable.class.getName(); 
    Cloneable.class.getName(); 
    Iterable .class.getName(); 
    Collection.class.getName(); 
    AbstractCollection.class.getName(); 
    Set.class.getName(); 
    AbstractSet.class.getName(); 
    HashSet.class.getName(); 
} 

は正しい順序でロードします。それは醜いですが、それは動作します。

関連する問題