AspectJ 可以通过 sun.net.* 包编织吗? [英] Can AspectJ weave through sun.net.* packages?

查看:21
本文介绍了AspectJ 可以通过 sun.net.* 包编织吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 AspectJ 来拦截 java.net.Socket 调用.

I'm using AspectJ to intercept java.net.Socket calls.

我创建了非常简单的方面

I've created very simple aspect

after(): call(* java.net.Socket.connect(..)) {
    System.out.println("Connect intercepted!");
}

和 aop.xml

<aspectj>

    <aspects>
        <aspect name="com.iggroup.lightstreamer.nwtp.SocketExceptionLoggingAspect"/>
    </aspects>

    <weaver options="-Xlint:ignore -Xset:weaveJavaxPackages=true -Xset:weaveJavaPackages=true">
    </weaver>

</aspectj>

当调用栈是这样的时候,就可以看到控制台输出了:

When the call stack is like this, then I can see the console output:

java.lang.Exception
    at com.iggroup.lightstreamer.nwtp.SocketExceptionLoggingAspect.ajc$after$com_iggroup_lightstreamer_nwtp_SocketExceptionLoggingAspect$2$6e16217c(SocketExceptionLoggingAspect.aj:39)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:337)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:134)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)
    at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:91)
    at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
    at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:596)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:557)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:475)
    at com.iggroup.lightstreamer.nwtp.users.SsoRestClientImpl.lambda$0(SsoRestClientImpl.java:68)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

但是当调用栈是这样的时候什么都没有注销:

But nothing is logged out when the call stack is like this:

Caused by: java.net.ConnectException: Connection refused: connect
                at java.net.DualStackPlainSocketImpl.connect0(Native Method) ~[na:1.8.0_65]
                at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79) ~[na:1.8.0_65]
                at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_65]
                at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_65]
                at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_65]
                at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) ~[na:1.8.0_65]
                at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_65]
                at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_65]
                at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:668) ~[na:1.8.0_65]
                at sun.security.ssl.BaseSSLSocketImpl.connect(BaseSSLSocketImpl.java:173) ~[na:1.8.0_65]
                at sun.net.NetworkClient.doConnect(NetworkClient.java:180) ~[na:1.8.0_65]
                at sun.net.www.http.HttpClient.openServer(HttpClient.java:432) ~[na:1.8.0_65]
                at sun.net.www.http.HttpClient.openServer(HttpClient.java:527) ~[na:1.8.0_65]
                at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:781) ~[na:1.8.0_65]
                at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:647) ~[na:1.8.0_65]
                at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1536) ~[na:1.8.0_65]
                at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441) ~[na:1.8.0_65]
                at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254) ~[na:1.8.0_65]
                at com.lightstreamer.ls_client.HttpProvider.connectAndGetAnswer(HttpProvider.java:244) ~[lightstreamer-se-client-2.5.2-1110.jar:na]

我想知道是否是因为 sun.net.* 包由于某些安全管理器限制而未在加载时编织.

I wonder if it is because the sun.net.* packages are not load-time-weaved due to some security manager restrictions.

有谁知道如何让它与 sun.net.* 包一起工作?

Does anyone know how to get it work with sun.net.* packages?

更新 1

我确认我可以拦截 ls_client.HttpProvider.connectAndGetAnswer 调用,但不能拦截它上面的调用 (sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream).

I confirm that I can intercept the ls_client.HttpProvider.connectAndGetAnswer call, but not the one above it (sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream).

sun.* 可以用 AspectJ 编织吗?

Is sun.* possible to weave with AspectJ?

推荐答案

我还没有看到 JRE(引导程序)类的加载时编织的成功设置.如果您出于调试目的需要它,我会转而使用 JRE 类的构建时间编织.

I'm yet to see a successful setup for load-time weaving of JRE (bootstrap) classes. If you need this for debugging purposes I'd go with build time weaving of the JRE classes instead.

这个简短的片段将为您编织 JRE jar,并将编织的类放在单个输出 jar 中.它需要 org.aspectj/aspectjtools 作为依赖项.它还会跳过 JRE 的 ext 子文件夹中的 jar,因为这些 jar 将包含一些重复的类,并且创建包含重复文件的 jar 文件将导致错误.我也在较新的 JRE 版本中跳过 jfxswt.jar,因为它会因为缺少类而失败.

This short snippet will weave the JRE jars for you and put the weaved classes in a single output jar. It needs org.aspectj/aspectjtools as a dependency. It also skips the jars in ext subfolder of the JRE as those jars will contain some duplicate classes and creating a jar file containing duplicate files will lead to an error. I'm also skipping jfxswt.jar from newer JRE versions as it will fail because of missing classes.

String aspectFileName = "src/main/java/pckg/AspectName.aj";
String jreLibPath = "c:/Program Files/Java/jdk1.8.0_40/jre/lib";
String outputJar = "weavedjre.jar";

List<String> jars = new ArrayList<>();

File dir = new File(jreLibPath);
File[] files = dir.listFiles();
for (File file : files) {
    if (file.isFile() && file.getName().endsWith(".jar")
            && !file.getName().endsWith("jfxswt.jar")) {
        jars.add(file.getAbsolutePath());
    }
}

List<String> ajcArgs = new ArrayList<>(Arrays.asList("-showWeaveInfo"));
for (String jar : jars) {
    ajcArgs.add("-inpath");
    ajcArgs.add(jar);
}
ajcArgs.add(aspectFileName);
ajcArgs.add("-outjar");
ajcArgs.add(outputJar);

org.aspectj.tools.ajc.Main.main(ajcArgs.toArray(new String[] {}));

然后使用以下 VM 参数运行您的程序以使用编织的 JRE 类(预先添加到您的引导类路径):

Then run your program with the following VM arguments to use the weaved JRE classes (prepended to your boot classpath):

-verbose:class -Xbootclasspath/p:path_to/weavedjre.jar

或在 Eclipse 启动配置中:

or in an Eclipse launch configuration:

-verbose:class -Xbootclasspath/p:${resource_loc:/project_name/weavedjre.jar}

我还添加了类加载 VM 参数的详细日志记录,因此您可以查看从何处加载了哪个类.

I added the verbose logging of class loading VM argument too, so you can see which class is loaded from where.

这篇关于AspectJ 可以通过 sun.net.* 包编织吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆