20

无极4《Q2404-8305 》Java代理是一种特殊类型的类,通过使用Java插装API,它可以拦截运行在JVM上的应用程序,修改它们的字节码。Java代理并不是一项新技术。相反,它们从Java 5开始就存在了。但即使在所有这些时间之后,许多开发人员仍然对这个特性有误解——而其他人甚至不知道它。

在这篇文章中,我们通过给您一个关于Java代理的快速指南来解决这个问题。您将了解Java代理是什么,使用它们的好处是什么,无极4注册登录网址以及如何使用它们来分析Java应用程序。让我们开始吧。

新的文字-动作

定义Java代理

Java代理是Java插装API的一部分。为了理解代理,我们需要理解仪器是什么。

在软件的上下文中,工具是一种用于更改现有应用程序并向其添加代码的技术。您可以手动和自动地执行检测。您还可以在编译时和运行时进行此操作。

那么,无极四荣耀注册仪表有什么用呢?它允许你改变代码,改变它的行为,而不需要编辑它的源代码文件。这可能非常强大,也很危险。你能做什么就交给你了。可能性是无限的。面向方面的编程吗?变异测试?分析吗?你的名字。

解决了这些问题之后,让我们再次关注Java代理。这些东西是什么,它们和仪器仪表有什么关系?

简而言之,Java代理只不过是一个普通的Java类。不同的是它必须遵循一些特定的约定。第一个约定与代理的入口点有关。入口点由一个名为“premain”的方法组成,其签名如下:

 public static void premain(String agentArgs, Instrumentation inst) 

如果代理类没有具有上述签名的“premain”方法,它应该有以下替代方法:

public static void premain(String agentArgs) 

一旦JVM初始化,它就会调用每个代理的premain方法。然后,像往常一样调用Java应用程序的主方法。每个premain方法必须正常恢复执行,应用程序才能继续进入启动阶段。

代理还应该有另一个名为“agentmain”的方法。下面是该方法的两个可能特征:

 public static void agentmain(String agentArgs, Instrumentation inst) 
 public static void agentmain(String agentArgs) 

当代理不是在JVM初始化时调用,而是在JVM初始化之后调用时,才会使用这些方法。

如何编写Java代理

实际上,java代理是一种特殊类型的.jar文件。正如我们已经提到的,要创建这样的代理,我们必须使用Java插装API。这样的API并不新鲜,我们之前也提到过。

创建代理所需的第一个成分是代理类。代理类只是一个普通的Java类,它实现了我们在前一节中讨论的方法。

要创建Java代理,我们需要一个示例项目。因此,我们将创建一个愚蠢的,简单的应用程序,它只做一件事:打印斐波那契序列的前n个数字,n是用户提供的数字。一旦应用程序启动并运行,我们将使用一点Java插装来执行一些基本的分析。

构建示例应用程序

对于这个项目,我将使用免费的IntelliJ IDEA社区版,但是您可以使用您觉得最舒服的IDE或代码编辑器。所以,让我们开始吧。

打开IDE,点击“创建新项目”,如下图所示:

在“创建新项目”窗口中,选择“Java”作为项目类型,点击“Next:”

然后在下一画面中,在“从模板创建项目”框中,选择应用程序的“命令行App”模板,再次点击“next”:

在此之后,剩下的惟一工作就是配置项目的名称和位置,并单击“Finish:”

创建项目后,让我们创建斐波那契逻辑。复制以下内容并粘贴到你的主类:

package com.company;
 import java.util.Scanner;

 public class Main {

     public static void main(String[] args) {
         Scanner scanner = new Scanner(System.in);
         System.out.println("How many items do you want to print?");
         int items, previous, next;
         items = scanner.nextInt();
         previous = 0;
         next = 1;

         for (int i = 1; i <= items; ++i)
         {
             System.out.println(previous);
             int sum = previous + next;
             previous = next;
             next = sum;
         }
     }
 } 

这个应用程序超级简单。它开始询问用户希望打印的条目数量。然后,它生成并输出与用户通知的词汇数相同的Fibonacci序列。

当然,这个应用程序非常幼稚。例如,它不检查无效的项目。另一个问题是,如果用户输入的值足够大,就会导致程序溢出int的上限,无极四注册可以使用long甚至BigInteger类来处理更大的输入。但是,对于我们的示例,这些都不重要,所以如果您愿意,可以作为练习添加这些改进。

启动Java代理

我们的示例应用程序已经启动并运行,因此我们准备创建Java代理。重复创建新项目的过程。称之为“MyFirstAgentProject。”

然后,将类命名为“MyFirstAgent”并按enter。之后,将创建的文件的内容替换为以下内容:

package com.company;
 import java.lang.instrument.Instrumentation;

 public class MyFirstAgent {

     public static void premain(String agentArgs, Instrumentation inst) {
         System.out.println("Start!");
     }
 } 

现在我们必须创建一个自定义清单。让我们从向项目中添加Maven支持开始。右键单击“MyFirstAgentProject”模块。然后,点击“添加框架支持”。

在“添加框架支持”窗口中,选中“Maven”并单击OK。在那之后,IntelliJ将创建一个pomm .xml文件并打开它以便你可以编辑。将以下内容添加到pom.xml文件并保存:

 <build>
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-jar-plugin</artifactId>
                 <version>3.2.0</version>
                 <configuration>
                     <archive>
                         <manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
                     </archive>
                 </configuration>
             </plugin>
         </plugins>
     </build>
 <properties>
         <maven.compiler.source>1.6</maven.compiler.source>
         <maven.compiler.target>1.6</maven.compiler.target>
     </properties> 

在上面的代码中,我们将“maven-jar-plugin”插件添加到pom文件中,并为清单文件配置位置。现在我们需要创建它。为此,复制以下内容,将其粘贴到一个新文件中,并将其保存为“src/main/resources/META-INF/MANIFEST.MF”。

我们快到了!完成清单创建之后,现在让我们执行maven安装。在“Maven”工具窗口中,展开“Lifecycle”文件夹,右键单击install,然后检查“Build后执行”选项。

通过该设置,IDE将在每次构建应用程序时执行maven安装。所以,让我们来构建它吧!去构建>构建项目,或使用CTRL + F9快捷键。如果一切顺利,您应该能够在“target”下找到结果jar文件。

我们已经成功地为第一个Java代理创建了jar文件。现在,让我们测试一下!

加载代理

我们现在要使用代理,要做到这一点,我们需要加载它。加载Java代理有两种方法,分别称为静态加载和动态加载。静态加载发生在应用程序运行之前。它调用premain方法,并且在运行应用程序时通过使用-javaagent选项激活该方法。另一方面,动态加载是在已经运行的应用程序中激活的,这是使用Java Attach API完成的。

这里我们将使用静态加载。在IntelliJ IDEA中打开示例应用程序,运行>编辑配置,如下图所示:

将显示一个新窗口。在那里,您可以配置关于应用程序运行和调试的许多不同选项。现在需要做的是将-javaagent选项添加到VM选项字段中,将代理的jar文件的路径作为参数传递给它。

配置完路径后,可以单击OK,然后像往常一样运行项目。如果一切正常,您应该看到以下输出:

如您所见,消息“开始!”我们使用premain方法定义的,在运行应用程序的main方法之前打印出来。这意味着我们的代理已成功加载。

Start!
 How many items do you want to print?
 10
 0
 1
 1
 2
 3
 5
 8
 13
 21
 34

 Process finished with exit code 0 

接下来会发生什么?

你可能会想,我们所看到的一切是否太麻烦而没有什么结果。对此的回答是坚决的“不”。首先,您必须记住,对于Java代理,我们这里的示例是等效的“Hello world”。事情可以——而且确实——比这要复杂得多。正如我们已经提到的,有一些非常复杂的工具使用了Java插装API。

其次,请记住,可以使用许多其他工具将Java插装的功能真正扩展到新级别,例如允许您执行字节码操作等操作。另外,考虑到评测方面,大部分繁重的工作已经为你完成了。现在有很多强大的工具,它们以不同的类型出现,可以满足几乎所有的分析需求。

相关文章
为您推荐
各种观点

报歉!评论已关闭.