前言

之前写过一篇尝试开发一个基于dubb-go的go与java通信的解决方案,由于当时没有深入研究而放弃。最近重启了这个项目,在解决了大小写调用与服务发现的问题后(后续会详细写一下解决方案),目前进度变为开发一个能够将指定目录的dto与service接口转换成go代码并且推送到第三方git上的maven插件。本以为能够简单将普通类的代码轻松转换,结果出现了几个问题,记录一下解决方法。

一、项目路径获取问题

如何创建插件开发类(Mojo)及设置goal不表,百度上有很多,快进到遇到问题的地方。

在普通类开发中,很轻松就可以获取类当前所在的路径。但是在Mojo类中,相同的代码获取到的位置是maven中插件的存放位置,需要更改获取方式。

maven提供了通过javadoc的注释进行赋值的功能,举个例子,当我想获取指定module下resources里的某个文件时:

java 大漠插件 键盘操作 java调用大漠插件视频_maven

通过此种方式即可获取。

常用的参数有:

java 大漠插件 键盘操作 java调用大漠插件视频_java 大漠插件 键盘操作_02

内置属性

主要有两个常用内置属性:${basedir}项目的根目录(包含pom.xml文件的目录),${version}项目版本

POM属性

用户可以使用该属性引用POM文件中对应元素的值,常用的POM属性包括:

${project.build.sourceDirectory}:项目的主源码目录,默认为 src/main/java

${project.build.testSourceDirectory}:项目的测试源码目录,默认为 src/test/java

${project.build.directory}:项目构件输出目录,默认为 target/

${project.outputDirectory}:项目主代码编译输出目录,默认为 target/classes/

${project.testOutputDirectory}:项目测试代码编译输出目录,默认为 target/test-classes/

${project.groupId}:项目的 groupId

${project.artifactId}:项目的 artifactId

${project.version}:项目的 version,与${version}等价

${project.build.fianlName}:项目打包输出文件的名称。默认为${project.artifactId}-${project.version}

java 大漠插件 键盘操作 java调用大漠插件视频_java 大漠插件 键盘操作_02

二、加载类的问题

普通类中,加载的原方法为:

java 大漠插件 键盘操作 java调用大漠插件视频_maven_04

java 大漠插件 键盘操作 java调用大漠插件视频_java_05

(此代码抄自网上,实际上将classLoader传入下面的方法里通过loadClass的方法即可)

然而在插件中,通过Thread.currentThread().getContextClassLoader()无法将class文件加载。在http://maven.apache.org/guides/mini/guide-maven-classloading.html#guide-to-maven-classloading中可以看到,有四种ClassLoader,我们需要关心的是第三种plugin。官方文档表明解决方案有两种,一是在plugin中加上dependencies,我稍微尝试了一下没成功,并且每次使用插件都添加依赖的方式确实不太舒服,于是采用了第二种方案:

java 大漠插件 键盘操作 java调用大漠插件视频_java 大漠插件 键盘操作_06

在类中添加了一个注释,同时添加了一个变量,通过这种方式我们可以获取运行时所依赖的类。

java 大漠插件 键盘操作 java调用大漠插件视频_java调用maven插件_07

java 大漠插件 键盘操作 java调用大漠插件视频_java 大漠插件 键盘操作_08

红框为新的ClassLoader方式,蓝框为前文所述的加载类的方法

第三方库的拉取与推送

本来是准备用jgit做git submodule的,但是虽然pull没问题,add与commit却始终不行。最后,在同事的提醒下,选择了直接调用shell命令来进行自动拉取与推送。需要注意的是,git命令需要在submodule下,所以使用的时候需要将cd命令与git命令同时执行,中间加\n进行分割即可。

另外,加载class之前一定要已经编译好文件到target,所以在生成代码的方法里,添加了mvn clean与mvn compile的shell命令执行,保证生成代码时读取的java类是最新的。