`
xpenxpen
  • 浏览: 726070 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Maven plugin开发之classloader问题

 
阅读更多
本文第1,2节是maven插件开发的一些基础笔记。第3节是本文的重点,记录了笔者在开发maven插件时遇到的classloader问题。

1.如何做一个maven的plugin?

让你的类extends AbstractMojo,然后覆盖execute方法就可以了。
我的理解:maven的plugin可以做到只是一层壳,可以在execute里面再去调用核心的做事的类,由此可以充分发挥想象,做到任何java能做到的功能,比如调用代码生成器在generate-sources阶段生成代码。
要使用mojo的api,以下一些dependency是要加入的(有些不是必须,可以酌情删除)。
<dependency>
	<groupId>org.apache.maven</groupId>
	<artifactId>maven-plugin-api</artifactId>
	<version>2.0</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>org.apache.maven</groupId>
	<artifactId>maven-plugin-descriptor</artifactId>
	<version>2.0</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>org.apache.maven</groupId>
	<artifactId>maven-project</artifactId>
	<version>2.0</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>org.apache.maven</groupId>
	<artifactId>maven-model</artifactId>
	<version>2.0</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>org.apache.maven</groupId>
	<artifactId>maven-artifact</artifactId>
	<version>2.0</version>
	<scope>provided</scope>
</dependency>


2.${project.build.directory}表示什么意思
表示工程的target目录,
maven自带了哪些properties,可以参考http://docs.codehaus.org/display/MAVENUSER/MavenPropertiesGuide

3.classloader问题

3.1 maven在加载类方面使用了 ClassWorlds类库,所以是有一点复杂的。
一个典型的需求:如何在自己写的mojo里调用到某个特定jar包下的类呢。直接用Class.forName是会报类找不到的错的。
这点在官方文档上提到了一些。
http://maven.apache.org/guides/mini/guide-maven-classloading.html
其中第3节. Plugin Classloaders。这一节提到可以用 ${plugin.artifacts}这个表达式来得到运行时的依赖。

官方Cookbook给出了示例代码
http://docs.codehaus.org/display/MAVENUSER/Mojo+Developer+Cookbook

/** @parameter default-value="${plugin.artifacts}" */
private java.util.List pluginArtifacts;


我试验了以后发现是有问题的。首先用这个表达式Maven2和Maven3就不兼容,2种版本运行下来得到的dependency不一样。
其次即使得到了,dependency list也是不全的,这点可以在这个网页上得到佐证,http://maven.40175.n5.nabble.com/For-Plugin-Developers-Usage-of-plugin-artifacts-expression-td209073.html
maven在解析dependency的时候做了一点filter,所以这样就蛋疼了,得到的jar包不全,而我要的那个类所在的jar包就没有在这个解完的dependency list里。

3.2 classloader问题的一个解决方案:
http://stackoverflow.com/questions/871708/maven-plugin-cant-load-class/4921612#4921612

关键代码如下
List runtimeClasspathElements = project.getRuntimeClasspathElements();
URL[] runtimeUrls = new URL[runtimeClasspathElements.size()];
for (int i = 0; i < runtimeClasspathElements.size(); i++) {
  String element = (String) runtimeClasspathElements.get(i);
  runtimeUrls[i] = new File(element).toURI().toURL();
}
URLClassLoader newLoader = new URLClassLoader(runtimeUrls,
  Thread.currentThread().getContextClassLoader());
 
这个方案我试过了,的确是可以的,但是Maven2和Maven3不兼容,还是这个问题,2种版本运行下来得到的dependency不一样。
而且有一个强制要求:你要的那个类所在的jar包必须加到你这个工程的dependency里去,采用compile phase,不然getRuntimeClasspathElements是得不到的。
问题是plugin需要什么jar那是plugin的事,为何要强制我工程加这个jar包呢,有时候我们不想让这个jar包进dependency,那怎么办呢?

3.3 classloader问题的另一个解决方案:
没辙了,只能把需要的jar包url当作参数传进mojo里来了,plugin怎么传参的可以在pom里<configuration>里面配置,具体就不展开了。


分享到:
评论

相关推荐

    maven-classloader-plugin:只是针对Maven插件中的类加载问题的实验

    总之,"Maven-classloader-plugin"是一个针对Maven插件类加载问题的解决方案,它提供了一种灵活的方式来管理插件的类加载行为,帮助开发者解决因类加载引发的复杂问题。通过对这个插件的理解和应用,开发者可以更...

    xjar-maven-plugin:XJar-Maven-Plugin是对XJar的一个Maven插件封装,实现可通过Maven命令或绑定在Maven的生命周期之中执行,以更便捷的方式集成XJar

    XJar-Maven-Plugin是对的一个Maven插件封装,实现可通过Maven命令或绑定在Maven的生命周期之中执行,从而更加便捷的方式集成了 。 GitHub: : 什么是XJar XJar是基于对JAR包内部资源的加密以及扩展ClassLoader来...

    apache-maven-3.8.4.zip

    2. **boot** 目录:包含用于启动Maven内嵌的Jetty服务器的类加载器(ClassLoader)。 3. **conf** 目录:存储Maven的配置文件,比如`settings.xml`,它定义了Maven的全局配置,如本地仓库位置、远程仓库和代理设置...

    apache-maven-3.3.3.zip

    依赖管理是Maven的一大特色,通过在POM文件中声明项目依赖,Maven会自动下载并管理这些依赖及其版本,避免了版本冲突问题。此外,Maven还支持插件系统,允许开发者扩展Maven的功能,以满足特定的构建需求。 Maven...

    ClassFinal字节码加密工具-其他

    classfinal-maven-plugin:ClassFinal加密的maven插件;功能特性:无需修改原项目代码,只要把编译好的jar/war包用本工具加密即可。运行加密项目时,无需求修改tomcat,spring等源代码。支持普通jar包、springboot ...

    junit-platform-maven-plugin:Maven插件启动JUnit平台

    使用库通过专用的ClassLoader实例分别加载测试类,主类和框架/插件类。 该插件由在Devoxx 2018上提出: ://youtu.be/l4Dk7EF-oYc t 2346 先决条件 使用此插件至少需要: 简单用法 以下各节描述了此插件的默认和...

    Java之——类热加载

    在开发环境中,我们可以使用Maven的`maven-compiler-plugin`和`maven-surefire-plugin`等插件配置热加载。例如,使用`maven-surefire-plugin`的`rerunFailingTestsCount`属性可以重试失败的测试,有时这也可以达到...

    java class reload

    6. **使用maven的tomcat7-maven-plugin或tomcat8-maven-plugin** - Maven插件可以在开发过程中自动部署项目到Tomcat,并且在每次构建时自动更新,提供类的热替换。 7. **注意事项** - 类的热重载可能不适用于所有...

    springBoot学习笔记整理

    在实际项目开发过程中,开发人员经常会遇到修改代码后需要重新启动应用才能看到效果的问题,这不仅增加了开发时间成本,也降低了开发效率。因此,热部署和代码变更检测成为了提高开发效率的关键技术之一。 #### 热...

    jar包隔离代码.zip

    4. Maven的maven-shade-plugin:通过重打包机制,将所有依赖合并到一个jar中,解决依赖冲突。 三、代码示例解析 "jar包隔离代码.zip"中的代码可能是实现了自定义ClassLoader的示例,或者利用了某种隔离技术的解决...

    weblogic下开发web项目时修改java文件不用重启的绿色方法,不用修改weblogic的配置文件、不用jar

    不过,需要注意的是,这种方法虽然提高了开发效率,但在生产环境中应谨慎使用,因为热部署可能带来的稳定性问题和性能影响。在开发阶段,确保及时测试和验证更改,以确保应用的正确性和稳定性。

    通过自定义Gradle插件修改编译后的class文件

    在Java开发中,Gradle是一种广泛应用的构建自动化工具,它允许开发者通过编写Groovy或Kotlin DSL脚本来管理项目的构建过程。自定义Gradle插件是Gradle的强大特性之一,可以扩展其功能以满足特定项目需求。本篇将详细...

    light-jpf:轻量级Java插件框架

    特点简单的API 使用自定义Java类加载器进行沙箱测试使用Maven构建插件2.用法2.1创建插件创建实现ljpf.Plugin接口的Plugin类。 public class CustomPlugin implements Plugin { @Override public void load () { ... ...

    附带资源的jar包

    在Maven中,可以配置`&lt;resources&gt;`标签来指定资源文件夹,并通过`maven-jar-plugin`插件将它们打包进jar。 资源的访问在Java中是通过类加载器完成的。例如,我们可以通过`Class.getResource()`或`Class....

    在可执行jar中载入第三方jar的几个解决方法

    使用如Apache Maven的`maven-shade-plugin`或Gradle的`Shadow`插件可以实现这个目标。 2. **自定义类加载器**:创建自己的类加载器,该加载器可以读取并加载外部JAR中的类。这样,即使在`-jar`模式下,也可以通过...

    Eclipse打包成JAR包读取外部JAR包和外部配置文件(源码)

    虽然问题中没有提到,但现代Java开发通常使用构建工具,如Maven或Gradle,它们能更方便地管理依赖并打包项目。Maven的`maven-jar-plugin`和Gradle的`jar`任务都可以配置来包含外部JAR和配置文件。 6. **运行JAR**...

    详解SpringBoot配置devtools实现热部署

    * 在 Maven 的 pom.xml 文件中添加插件:&lt;build&gt; &lt;plugins&gt; &lt;plugin&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt; &lt;configuration&gt; &lt;fork&gt;true&lt;/fork&gt; ...

    Tomcat优化1

    &lt;artifactId&gt;jspc-maven-plugin &lt;version&gt;2.1.0 &lt;/plugin&gt; ``` ClassLoader 配置 在 Tomcat 中,ClassLoader 是一个重要的组件,负责加载 Java 类。在 conf/context.xml 文件中,我们可以配置 ClassLoader ...

    Springboot热部署实现原理及实例详解

    然后,在 build 中添加 spring-boot-maven-plugin 插件,并配置 fork 为 true。 DevTools 工具包可以实现页面热部署、类文件热部署和对属性文件的热部署。它可以监听 classpath 下的文件变动,并且会立即重启应用...

Global site tag (gtag.js) - Google Analytics