如何在Java程序中使用java.net.URL类监控已打开的URL?

3
我正在处理一个大型(包含许多类)的Java项目,我有它的源代码,但是大部分的类都是通过ClassLoaders动态创建或下载的。无论如何,我想要能够“重写”java.net.URL类,以便我可以追踪打开url的调用。我不能使用嗅探器,因为内容是SSL加密的。我尝试扩展java.net.URL,但它不起作用,因为这是一个final类。我还打开了java.net.URL的源代码并进行了修改,并成功构建了它,现在我该如何使默认的java classloader加载我的修改后的java.net.URL而不是原始的类呢?任何建议都欢迎!先感谢您。
4个回答

3

谢谢您的快速回答。这是我第一次使用stackoverflow.com(当然是用于提问,哈哈)。我以前从未使用过AspectJ,但它听起来很完美,添加另一个依赖项也没有问题。我正在尝试弄清楚它的工作原理,但实际上无法理解其语法。我找到了这个:Pointcut("execution(* new(..))")看起来像是我们在挂钩函数调用,对吧? 但我仍然不知道如何拦截对java.net.URL构造函数的调用。您能否为首次使用AspectJ的用户提供一些代码?再次感谢。 - Marcio S Monteiro
你好Marcio, 我编辑了我的答案,并添加了一个链接到我的博客,在那里你可以找到有关AOP的简短介绍演示文稿(还包括1个代码示例!)。你也可以在网上找到很多关于AOP的材料。构造函数切点可以这样定义:call(URL.new(..))希望这可以帮助你解决问题。祝好,Nils! - Nils Schmidt

2
你无法扩展URL,正如你所发现的那样。你也许可以让JVM加载你自定义版本的类,但在我看来,这听起来像是一场噩梦。
幸运的是,你可以实现一个自定义的 URLStreamHandlerFactory 并通过 URL.setURLStreamHandlerFactory() 注册它。这将允许你包装和监控当URL打开流时的情况,就像你想要的那样。
编辑
但如果你的应用程序已经注册了一个URLStreamHandlerFactory,你将无法使用这种方法;URLStreamHandlerFactories是1/app的。许多类型的应用容器使用其中之一(例如Tomcat),所以如果你正在使用其中之一,你就会遇到问题。

另一个问题是实现URLStreamHandlerFactory并不是微不足道的,因为您必须重新实现VM特定逻辑以查找适用于不同协议的适当处理程序实现。 - jarnbjo

1

你有考虑过使用AspectJ吗?你可以在URL构造函数上设置一个切入点,从而在任何新的URL实例创建时得到通知。


0

如果您修改了标准API中的类,则必须在引导类路径中添加您的类(JAR或目录),否则VM内部类将优先于添加到普通类路径中的任何类。使用Sun的VM,您可以使用参数-Xbootclasspath/p:添加具有比内部实现更高优先级的新类。

另一种选择是,在不修改URL实现的情况下实现ProxySelector。打开URLConnection将导致URL实现查询ProxySelector.select(URI uri)以获取给定地址的适当代理。即使您实际上正在使用代理,这也将起作用。您可以使用ProxySelector.getDefault()获取系统ProxySelector,然后在注册自己的实现之前将select调用委派给原始实现,并在跟踪传递给select方法的URI之后。


参数 -Xbootclasspath/p: 可以解决问题,但我想先尝试使用其他人建议的 AspectJ。最好不要搞乱默认实现,对吧? - Marcio S Monteiro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接