不知道javaagent是什么,运行个hello world就知道了

裴景
• 阅读 1153

从事java开发的同学,或多或少听说过java探针/javaagent这个术语。本文不说它的定义,不说它的原理,不说它的高大上的作用,只说它的"hello world"。即运行一个最简单的例子,实际看看效果,有了真切的感受后,产生真切清晰的认识,以便快速的入门并深入探索。

编码

用idea创建个maven项目,如下图,项目名称随意,这里我的项目名为:microservice-comb-javaagent
不知道javaagent是什么,运行个hello world就知道了

代码如下
首先,创建一个类:AgentDemo

public class AgentDemo {
    /**
     * 该方法在main方法之前运行,与main方法运行在同一个JVM中
     */
    public static void premain(String agentArgs, Instrumentation inst) {
        System.out.println("------ premain方法 有两个入参 ------ agentArgs:" + agentArgs + " inst:" + inst.toString());
    }

    /**
     * 如果不存在 {@link AgentDemo#premain(String, Instrumentation)}, 则会执行本方法
     */
    public static void premain(String agentArgs) {
        System.out.println("------ premain方法,有一个入参 ------ agentArgs:" + agentArgs);
    }
}

注意:AgentDemo的全限定名会在pom.xml中标签Premain-Class引用

其次,再创建一个类:AgentTest

public class AgentTest {
    public static void main(String[] args) {
        System.out.println(" ------ main方法");
    }
}

再次,在项目的pom.xml中添加

   ··· 略

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifestEntries>
                        <!-- 值为包含premain方法的类. 启动方式为命令行启动时,javaagent JAR文件清单必须包含 Premain-Class 属性, 代理类必须实现 public static premain()-->
                        <Premain-Class>com.skyler.cobweb.agent.AgentDemo</Premain-Class>
                        <Can-Redefine-Classes>true</Can-Redefine-Classes>
                        <Can-Retransform-Classes>true</Can-Retransform-Classes>
                    </manifestEntries>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

打jar包

microservice-comb-javaagent打成jar包。运行时会使用这个Jar包.打包命令:mvn clean package。结果如下图
不知道javaagent是什么,运行个hello world就知道了

运行

你可以有两个运行方式:idea中直接运行命令行运行

  • idea中直接运行

需要配置下项目的运行配置的VM options,如下图,形式为-javaagent:jarpath[=options]; 我的内容为:-javaagent:/Users/xx/microservice-comb/microservice-comb-javaagent/target/microservice-comb-javaagent-1.0.0-SNAPSHOT.jar=hello world

不知道javaagent是什么,运行个hello world就知道了

然后,运行AgentTest.main方法,结果如下图
不知道javaagent是什么,运行个hello world就知道了

可以看到,打印出了AgentDemo.premain方法的信息

  • 命令行运行

cd到项目microservice-comb-javaagent的/target/classes路径下

$ cd xx/target/classes
$ java -javaagent:/Users/xx/microservice-comb/microservice-comb-javaagent/target/microservice-comb-javaagent-1.0.0-SNAPSHOT.jar="hello world"  com.skyler.cobweb.agent.AgentTest

可以看到,同样打印出了AgentDemo.premain方法的信息
不知道javaagent是什么,运行个hello world就知道了

收获

这里有个对比,运行时是否加上-javaagent:jar,这个给你的感受会很明显和透彻。来再操作下

加上时

$ cd /Users/xx/microservice-comb/microservice-comb-javaagent/target/classes
$ java -javaagent:/Users/xx/microservice-comb/microservice-comb-javaagent/target/microservice-comb-javaagent-1.0.0-SNAPSHOT.jar="hello world" com.skyler.cobweb.agent.AgentTest

效果

------ premain方法 有两个入参 ------ agentArgs:hello world inst:sun.instrument.InstrumentationImpl@a09ee92
 ------ main方法

不加上时

$ cd /Users/xx/microservice-comb/microservice-comb-javaagent/target/classes
$ java com.skyler.cobweb.agent.AgentTest

效果

 ------ main方法

效果还是很明显的,不加-javaagent,jar里的类方法没有执行,也即不会输出信息

这个对比的目的是突出javaagent的作用。并让你清晰的感受javaagent的作用:像代理一样可以在main方法前做些事情,官方的说字节码增强。通过修改字节码的方式,让开发者有机会做些事情,如arthas 和skywalking的建监听组件

千言万语抵不上run一个'hello world'

本文想通过最简单、最直观的方式,让你最快速的、最真切的了解javaagent的作用。下篇展开说javaagent的原理和更实际的使用例子

点赞
收藏
评论区
推荐文章
Python进阶者 Python进阶者
4年前
厉害了,Python也能操作注册表
前言大家好,我是IT共享者,人称皮皮。注册表这个东西大家可能都不是很熟悉,因为我们平时用到的少;但是它是Windows的核心,很多软件的启动和日志记录什么的都包含在里面,可以说它是一个大型的数据库也不为过,今天我们就来看看Python是如何操作注册表的吧。一、注册表初次见面进入系统注册表的方法多种多样,最常见的就是运行窗口输入命令“regedit”,即可进
Easter79 Easter79
3年前
springboot使用hibernate validator校验
hibernatevalidatorBean验证器在开发中常用,这里我们说说它在springboot中的使用第一步:引入配置@BeanpublicMethodValidationPostProcessormethodValidationPostProcessor(){MethodValid
浩浩 浩浩
4年前
JVM--虚拟机方法调用
概述Java能做到一次编译,随处运行,最要是归功于java虚拟机和class文件,我们知道,计算机是0和1的世界,并且只认0和1,所以不管是什么语言什么编译类型,最终给计算机的都是0和1,java也不例外,但是我们的java编译成了class文件,class怎么就转换成0和1了呢,或者说机器码呢?其实这一步是虚拟机帮我们干的。当然,虚拟机是建立在不同
Karen110 Karen110
4年前
厉害了,Python也能操作注册表
前言大家好,我是IT共享者,人称皮皮。注册表这个东西大家可能都不是很熟悉,因为我们平时用到的少;但是它是Windows的核心,很多软件的启动和日志记录什么的都包含在里面,可以说它是一个大型的数据库也不为过,今天我们就来看看Python是如何操作注册表的吧。一、注册表初次见面进入系统注册表的方法多种多样,最常见的就是运行窗口输入命令“regedit”,即可
Wesley13 Wesley13
3年前
存储相关知识
最近在看一些存储相关的东西,就顺手作了一些总结。我发现国内在存储的知识普及方面做的还不错,因此就查阅了国内相关的一些资料,也并没有去看英文文档。下面就把整理的一些知识点发出来,方便大家学习交流,希望大家给我多提提意见。存储领域,有挺多的名词和术语,比如常见的有SCSI、FC、DAS、NAS、SAN等,下面就简单说说它们。SCS
Stella981 Stella981
3年前
Intellij ide 2017.2新建javaweb项目,并且部署
折腾IDE的确很费劲,都说它很强大,可是配置开发环境就费了很大的劲,下面就说一下详细的步骤,新建project就不说了,该添加SDK(javaJDK)这个照常添加java的安装路径就可以,在新建号project之后,接下来就是新建web项目了,IDE里是以moudle为单位的,这个跟eclipse的project接近吧,所以我们新建module:!
Wesley13 Wesley13
3年前
mysql 主从复制
mysql主从复制(超简单)怎么安装mysql数据库,这里不说了,只说它的主从复制,步骤如下:1、主从服务器分别作以下操作: 1.1、版本一致 1.2、初始化表,并在后台启动mysql 1.3、修改root的密码2、修改主服务器master:  vi/etc/my.cnf
Stella981 Stella981
3年前
Bugtags,最适合移动应用的智能 Bug 管理系统
Bug管理系统,技术同学都见过很多,和最适合移动应用、智能几乎扯不上半毛钱关系,就是一个登记Bug的工具而已。那么Bugtags(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.bugtags.com)的特别之处是什么呢?为什么说它是最适合移动应用
Stella981 Stella981
3年前
EL表达式及其11个使用对象(尤其提到了jsp中的对象)
转摘文章(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fwjlvivid.iteye.com%2Fblog%2F1395420)一、page对象page对象代表JSP本身,更准确地说它代表JSP被转译后的Servlet,它可以调用Servlet类所定义的方法
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
sum墨 sum墨
10个月前
《优化接口设计的思路》系列:第八篇—分页接口的设计和优化
分页查询的需求想必大家都做过吧,很简单,无非就是查询SQL后面加上limitpageNum,pageSize,复杂点的话加个排序。虽说它简单吧,但真正封装过分页组件的同学应该也不多吧,很多时候都是上网copy一份或者拿前辈封装好的。这篇文章呢,我就讲一下我是怎么做分页的,以及分页有哪些需要注意的点。