1. 写一个基于maven的插件
今天在写基于maven plugin的一个小程序,它的功能是在maven执行package 阶段将已经打好包,从这个包中抽取分布式服务中依赖的类,之后会将这些服务器端依赖的类打成一个包。也就是执行了mvn package之后会在工程的target中生成两个jar包,一个是服务器端部署包,一个是客户端依赖包。客户端依赖包是服务器端包的一个子集。
该插件就是负责抽取服务器端部署包中的类。插件的工程名称是distribute-build,插件开发完成之后,会在具体的项目中使用,我搞了一个实验项目koubei-dian,在koubei-dian 这个分包项目中的pom中增加一个插件的配置节点,如下所示
<project></project> <modelversion>4.0.0</modelversion> <build></build> .。。。。。。。。。 <plugins></plugins> <plugin></plugin> <groupid>com.koubei</groupid> <artifactid>distribute-build</artifactid> <version>1.0-SNAPSHOT</version> <configuration></configuration> <springconfig>dian.application.xml</springconfig> <port>9999</port> 。。。。。。。。。 |
2. 发现问题
然后在dos命令行中敲入下面这个命令:
/koubei-dian>mvn com.koubei:distribute-build:distill |
但是在执行distill这个goal时候出现了错误
java.lang.NoClassDefFoundError: com/koubei/util/Pager at java.lang.Class.getDeclaredMethods0(Native Method) at java.lang.Class.privateGetDeclaredMethods(Class.java:2427) at java.lang.Class.privateGetPublicMethods(Class.java:2547) at java.lang.Class.getMethods(Class.java:1410) at com.koubei.plugin.distribute.ClassMetaInfo.getAllDepandClass(ClassMet aInfo.java:51) at com.koubei.plugin.distribute.ServiceClassManager.execute(ServiceClass Manager.java:109) at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPlugi nManager.java:483) at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(Defa ultLifecycleExecutor.java:678) at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandalone Goal(DefaultLifecycleExecutor.java:553) at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(Defau ltLifecycleExecutor.java:523) at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHan dleFailures(DefaultLifecycleExecutor.java:371) at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegmen ts(DefaultLifecycleExecutor.java:332) at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLi fecycleExecutor.java:181) |
奇怪!我明明已经在koubeid-dian的pom中的depandance中添加了com/koubei/util/Pager 这个类所在包的依赖呀,为啥当前的classloader还是不能加载这个类呢?直觉告诉我应该是maven的classloader的加载机制的问题。于是还得依赖万能的google,终于我找到了maven reference网站上关于maven类加载机制的说明。http://maven.apache.org/guides/mini/guide-maven-classloading.html
这个文档中说了四种类加载机制,分别是:
1. System Classloader
2. Core Classloader
3. Plugin Classloaders
4. Custom Classloaders
其中我最关心的是plugin classloaders,这个类加载器从类加载的层次关系来看是继承与System classloader 和Core Classloader的,凭我想当然的理解在插件goal执行的时候插件的classloader已经包含的project pom 中申明的依赖包。但是,plugin classloader说明中有这么一句话:
Please note that the plugin classloader does neither contain the dependencies of the current project nor its build output. Instead, plugins can query the project's compile, runtime and test class path from the MavenProject in combination with the mojo annotation requiresDependencyResolution from the Mojo API Specification. For instance, flagging a mojo with @requiresDependencyResolution runtime enables it to query the runtime class path of the current project from which it could create further classloaders. |
翻译一下:
请注意,plugin classloader既不包含当前工程的dependencies,也不包含当前工程的输出目录。但是,如果你现在插件运行的时候想引用当前工程的编译(compile)、运行时(runtime)、测试(test)的classpath,可以通过MavenProject 这个组合在成员对象来调用,这个mojo对象需要有“requiresDependencyResolution”这个annotation |
3. 解决问题
通过以上说明,我知道解决当前maven plugin 不能正常加载类的问题可以通过两个方法解决:
方法1:在plugin配置的时候为plugin配置节点单独配置一个dependacne
<project></project> <modelversion>4.0.0</modelversion> <build></build> .。。。。。。。。。 <plugins></plugins> <plugin></plugin> <groupid>com.koubei</groupid> <artifactid>distribute-build</artifactid> <version>1.0-SNAPSHOT</version> <configuration></configuration> <springconfig>dian.application.xml</springconfig> <port>9999</port> <dependencies></dependencies> <dependency></dependency> <groupid>com.koubei</groupid> <artifactid>koubei-util</artifactid> <version>1.0.0</version> 。。。。。。。。。 |
添加如上蓝色加粗的dependencies节点。
方法2:在plugin类中添加MavenProject 一个成员对象,然后再类级别注释上添加@requiresDependencyResolution runtime注释项
1. /** 2. * @goal extract 3. * @phase package 4. * @requiresDependencyResolution test 5. */ 6. public class ServiceClassManager extends AbstractMojo { 7. 8. /** 9. * @parameter default-value="${project}" 10. * @required 11. * @readonly 12. */ 13. private MavenProject project; 14. 15. public void execute() throws MojoExecutionException { 16. 17. System.out.println(project.getArtifact().getFile().getAbsolutePath()); 18. 19. } 20. } |
通过以上这种方式就可以达到,不需要在plugin配置节点额外添加配置依赖来达到能够取道pom compile阶段需要依赖的那些jar包了。
完。。。。
分享到:
相关推荐
maven plugin maven plugin scm 项目管理 构建工具 antmaven plugin maven plugin scm 项目管理 构建工具 ant
Maven的类加载器插件只是针对Maven插件中的类加载问题的实验
maven plugin打包下载
eclipse maven plugin 插件 安装 和 配置
dockerfile-maven-plugin 支持 maven 直接发布项目至 docker 镜像库
Apache Tomcat Maven Plugin - About Apache Tomcat Maven Plugin
maven-tomcat-plugin让maven与tomcat配合得很好。它可以把应用部署到Tomcat服务器,也可以把tomcat作为内嵌服务器启动,就像jetty一样。 使用JPDA启动tomcat的远程调试功能。这样就能与eclipse配合起来,轻松地实现...
xjar-maven-plugin 项目相关jar包。包括xjar-maven-plugin-4.0.2.jar loadkitv1.0.1.jar xjar-4.0.2.jar
maven plugin, download for me
Maven使用tomcat8-maven-plugin插件
maven projects plugin出现红线怎么办,网上给许多比较蹩脚的方案。经过研究发现一个简洁的方法,一分钟就能搞定。
eclipse-maven3-plugin插件 包含apache-maven-3.3.9和eclipse-maven3-plugin
解决tomcat8-maven-plugin-3.0-r1655215.jar阿里云同有的问题。放到路径org\apache\tomcat\maven\tomcat8-maven-plugin\3.0-r1655215\就可以了
eclipse maven3插件,eclipse-maven3-plugin,m2e
yuicompressor-maven-plugin, 用于压缩 (Minify/Ofuscate/Aggregate) Javascript文件和使用 YUI 压缩器的CSS文件的Maven 插件 [[Flattr this git repo] ( http://api.flattr.com/button/flattr-badge-large.png)]...
maven的scala编译包
直接离线安装eclipse中的maven插件,在你的eclipse安装根目录下创建两个文件夹:links,myplugins(文件夹名字可以自定义),所在路径D:\eclipse。将下载下来的maven插件放到myplugins下。载links目录下创建一个...
修改版tomcat7-maven-plugin-2.2.jar
maven-maven-plugin-1.4.jar
Jenkins maven-plugin