代理传参
最近在学习使用一个开源的关系提取工具TCtracer,在使用过程中需要利用打包好的jar包向JVM进程中传递参数,因此就此记录一下流程和过程中遇到的问题及解决方案。
1. javaagent代理包配置
在IDEA界面有一个Edit Configurations,点击然后按界面左上角的+号:
在Modify options中选中Add VM options才会显示VM options:
然后在Application中进行javaagent和main方法的配置:
如TCTracer这个项目,仅添加了包的路径还是不能生成对应文件夹,此时需要配置一下项目前缀,帮助该工具寻找对应的函数/类同测试之间的连接,具体配置应该如下:
-javaagent:TCagent.jar包的绝对路径=classprefix=项目的前缀(如:edu.stanford.nlp.)
2. 代理包的运行
根据代理包的功能选择好main函数后,由于TCtracer是针对测试的工具,因此先对Maven项目进行test-compile,也在Edit Configurations里面进行配置+ Maven:
开始运行。
首先选择test-compile,点击运行按钮运行(或者命令行mvn test-compile):
运行完成后是完成了java项目的编译工作,生成了项目的.class文件,接下来可以传参数了。选中配置好的Application,点击运行:
3. 解决无法加载org.slf4j.impl.StaticLoggerBinder的错误
显示这个错误是因为依赖中没有加载对应的日志生成模块,因此需要在项目的pom.xml文件中加入或添加以下依赖:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version> <!--查找具有simple方法的版本-->
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version> <!--填入具体的simple版本-->
</dependency>
或者
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
如果发现加入依赖后现有的slf4j模块没有simple方法或者log方法,则需要更新maven库。
插入内容后显示标红,不要慌,点击如图所示的小图标(mac快捷键:command+shift+I)下载对应版本的包安装依赖即可:
安装完成后按上述步骤编译传参数即可。
4. 批量配置javaagent
4.1 手动配置javaagent(成功案例)
在需要配置大量Application时手动一个一个地配置真的很麻烦…但是实在没有查到批量配置的方法,毕竟每个Application都需要自命名和配置包或者Main方法,所以批量操作不太可能。但是有一个可以提升效率的小Tip:复制Application。复制后Application的配置会继承,包的查找也会定位到当前目录下,所以会方便很多。
在配置Application时会发现需要运行很多个Application,一个一个地运行就很不方便,因此需要配置一下,实现一键运行多个Application。
-
进去Edit Configuration
-
点击+号选择Compound
-
点击+选择添加需要运行的Application
即可批量运行Application。
如果是针对单元测试的Application。
选择添加Junit:
配置即可:
也可以直接将包加载进来进行配置:
要使得传参正确进行并且有效,则需要:
4.2 Maven中使用插件配置javaagent
虽然说有批量运行的方式,但是如果需要配置很多个,那么消耗也很大,所以通过修改maven项目的pom.xml文件设置插件直接进行jar包的传递就很有必要。
在pom.xml文件中插入如下内容(apache仓库的配置方法),由于传递参数需要在编译之后,测试之前,所以先跳过测试进行传参数,将surefire插件的skiptests配置成true:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>getClasspathFilenames</id>
<goals>
<goal>properties</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
<configuration>
<skiptests>true</skiptests>
<argLine>-javaagent:/Users/zhangmeixian/Desktop/Code/Codes/assert/tctracer/ctt-agent-p/build/libs/TCagent.jar</argLine>
</configuration>
</plugin>
有了插件,javaagent可以自动匹配传递参数。
根据自己的需要配置不同的插件,在pom文件中配置的插件会按照顺序执行。
Maven插件详解
但是有可能达不到想要的效果,因此另一种方式(org.codehaus仓库)配置:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<executable>java</executable>
<arguments>
<argument>-Xmx1000m</argument>
<argument>-javaagent:/Users/zhangmeixian/Desktop/Code/Codes/assert/tctracer/ctt-agent-p/build/libs/TCagent.jar</argument>
<argument>-classpath</argument>
<classpath/>
<argument>你要配置的类的在项目中的具体路径</argument>
</arguments>
</configuration>
</plugin>
类的具体路径是类似于:edu.stanford.nlp.classify.DatasetTest这种。
更新下载插件后,如果还标红,去查看自己maven对应的镜像仓库(如阿里镜像)是否有对应的版本,找到正确的版本号再下载,如果还标红,就重启IDEA。
这种方式执行插件的命令为:mvn exec:exec
5. 修改JVM进程全局参数
为了避免项目过大导致机器卡死,因此需要设置JVM的内存参数,手动设置过程如下:
点击Help-Edit Custom VM Options
会打开如下文件:
根据项目要求设定参数即可。