我正在尝试编写Java代理来拦截应用程序。在转换类时,我需要获取父类信息。因此,将调用Class.forName()方法来获取父类。当应用程序尝试创建MulticastSocket对象时,将在Windows平台上转换TwoStacksPlainDatagramSocketImpl类,然后在代理程序的transform方法中调用Class.forName(“java.net.AbstractPlainDatagramSocketImpl”)。但是,将抛出ClassCircularityError。 这只发生在JRE版本1.7.0_71和1.8.0_25之上。该应用程序使用旧的JRE版本运行良好。我已经简化了应用程序来重现问题。所以任何人都遇到过这个问题吗有人可以提供一些建议吗?
这是代理人的转换方法:
public byte[] transform(ClassLoader loader, String className,
Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
byte[] classfileBuffer) throws IllegalClassFormatException {
// TODO Auto-generated method stub
if (className.endsWith("java/net/TwoStacksPlainDatagramSocketImpl"))
try {
Class.forName("java.net.AbstractPlainDatagramSocketImpl");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Error e){
e.printStackTrace();
}
return null;
}
这是需要拦截的应用程序。
public class test {
public static void main(String[] args) throws ClassNotFoundException {
// TODO Auto-generated method stub
try {
MulticastSocket socket = new MulticastSocket();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这就是抛出的错误:
java.lang.ClassCircularityError: java/net/TwoStacksPlainDatagramSocketImpl
[Loaded java.net.TwoStacksPlainDatagramSocketImpl from D:\Share\jre1.7.0_76\lib\rt.jar]
at java.net.AbstractPlainDatagramSocketImpl.init(Native Method)
at java.net.AbstractPlainDatagramSocketImpl.<clinit>(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at com.ca.instrumentation.TestClassFileTransformer.transform(TestClassFileTransformer.java:16)
at sun.instrument.TransformerManager.transform(Unknown Source)
at sun.instrument.InstrumentationImpl.transform(Unknown Source)
at java.net.DefaultDatagramSocketImplFactory.createDatagramSocketImpl(Unknown Source)
at java.net.DatagramSocket.createImpl(Unknown Source)
at java.net.DatagramSocket.<init>(Unknown Source)
at java.net.MulticastSocket.<init>(Unknown Source)
at java.net.MulticastSocket.<init>(Unknown Source)
at test.test.main(test.java:11)