这是一个跟进java.net package - Override UDP transport。我在这里提出了一个新问题,因为我正在尝试一种解决问题的方法。我已经通过simlar问题了定制Classloader包括系统类的完整应用程序
java custom classloader: some classes are not loaded by my classloader
How to set my ClassLoader as the JVM's ClassLoader for loading ALL classes (jar classes included)?
,但没有运气。所以这是问题。
我想拦截在我的自定义类加载器中加载所有类(包括标准的JDK类)。这个想法是每当有DatagramSocket类的请求时就加载一个扩展类。我没有处理DatagramSocket何时以及如何在应用程序中实例化,因此我认为这是在我从主要方法启动应用程序之前截取此特定类的加载的最佳方法。为此我写了TestClassLoader,
public class MyClassLoader extends ClassLoader
{
public MyClassLoader(ClassLoader parent)
{
super(parent);
}
public Class loadClass(String name) throws ClassNotFoundException
{
System.out.println("loading " + name);
if (name.equals("java.net.DatagramSocket")
|| name.equals("MyDatagramSocket"))
{
System.out.println("Loading DatagramSocket class.... " + name);
return super.loadClass("MyDatagramSocket");
}
else
{
return super.loadClass(name);
}
}
}
和测试程序,
public class TestClassLoader
{
public static void main(String[] args) throws Exception {
//See if this invokes myClassLoader
DatagramSocket dSocket=new DatagramSocket();
System.out.println("DatagramSocket.classloader = "+DatagramSocket.class.getClassLoader());
//check the Class loader for the main class
System.out.println("TestClassLoader.classloader = " + TestClassLoader.class.getClassLoader());
}
}
和调用使用 “-Djava.system.class.loader = MyClassLoader” 选项的测试程序。我看到的输出是
loading java.lang.System
loading java.nio.charset.Charset
loading java.lang.String
loading TestClassLoader
DatagramSocket.classloader = null
TestClassLoader.classloader = [email protected]
我没有看到我的测试类加载器在DatagramSocket初始化时被调用。我做对了吗?
如果您试图拦截类加载,是否考虑使用自定义的javaagent? – 2015-02-11 18:22:03
不,我没有尝试过自定义Java代理。我是否可以使用javaagent实现相同的结果,即每当DatagramSocket创建时实例化我的扩展类?我不想修改标准DatagramSocket,因为这可能会导致一些授权问题。 – user572964 2015-02-11 19:38:07
必须在JVM启动时应用Java代理。但是您可以在加载类时进行修改。这并不容易,但是您可以用自己的实现来替换标准实现。 – 2015-02-11 22:13:29