如何给非maven的javaweb项目霸王硬上弓

最近在公司搭建了一套代码安全质量分析平台–著名的SonarQube开源版本,再配合jenkins组成自动化流程。

jenkins调用maven做源码编译打包,然后调用SonarQube进行代码扫描,看起来一点问题都没有。

但是问题来了,公司的项目都是非maven结构的javaweb项目。

上网查了一下,非maven结构的javaweb项目通过更多的定制配置,是完成可以用maven来编译打包的。

这两天碰到公司一个javaweb项目,结构比较特殊,项目里除了引用jar包,还引用了class文件,类似下面的结构

《如何给非maven的javaweb项目霸王硬上弓》

在网上查了半天,找不到这样项目结构使用maven的相关实践。运气比较好的是,之前帮公司配置 pinpoint agent 的时候,恰好了解了一个jvm参数 -classpath,经过在家的一系列实验,终于把这样项目结构的工程编译打包,pom的关键配置如下:

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                    <verbose>true</verbose>
                    <showWarnings>true</showWarnings>

                    <compilerArgs>
                        <arg>-extdirs</arg>
                        <arg>WebContent/WEB-INF/lib</arg>
                        <arg>-classpath</arg>
                        <arg>ImportedClasses</arg>
                    </compilerArgs>

                </configuration>
            </plugin>

在<compilerArgs>里设置编译用的jvm参数,除了常规引用的放在WebContent/WEB-INF/lib里的所有jar包,还有ImportedClasses目录下的
所有class文件。

这样就可以完美的进行编译和打包了。

回到公司配置好,编译,报错。有一个类的一个方法找不到。

这个项目还有一个特别之处,就是其中一个引用的class文件(且称它为a.class),跟其中一个jar包里的class文件的包名、类名一模一样,反编译看,两者内容却不一样。

按照上面的配置方法,maven在调用javac编译源码,会按顺序扫描依赖的文件,直到碰到第一个目标。

看下图,maven会从这个搜索路径里,按顺序去找依赖的类,请注意这里的排序:

  1. 先是jdk
  2. 然后到lib里的jar
  3. 最后到-classpath 指定的 ImportedClasses

《如何给非maven的javaweb项目霸王硬上弓》

回到那个报错,因为源码里引用的是 ImportedClasses 里的 a.class 才有的方法,而非 jar 里的a.class,当maven在扫描依赖文件时,首先会碰到 jar 里的 a.class,然后发现这个类没有这个方法,于是报错。

好了,说到这里,解决思路呼之欲出,就是让 ImportedClasses 的顺序比 lib 靠前。

这个方案网上找了一通,可能是因为拙略的搜索技巧,找不到别人提供的经验。

自己各种尝试,暂时也没有找到能调整顺序的方法。

舍弃javac 的-extdirs参数,全部依赖写到-classpath里,就可以自己掌控依赖的搜索顺序了。

                    <compilerArgs>
                        <arg>-classpath</arg>
                        <arg>ImportedClasses;WebContent/WEB-INF/lib/fastjson-1.2.47.jar</arg>
                    </compilerArgs>

《如何给非maven的javaweb项目霸王硬上弓》

把ImportedClasses写在所有jar之前,编择成功。

这个方法的缺点就是,当以来的jar包很多的时候,这个值就变得很长,因为要把每一个jar的路径写上去。

碰到这样的项目结构机率一般比较小,所以这也算是一个maven的冷门使用了。遗憾的是网上似乎找不到关于这种情况的解决方案,特意注册一个博客,以受批判。

    原文作者:Saga
    原文地址: https://segmentfault.com/a/1190000020377051
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞