解决Jersey 2.x Jersey 1.x冲突问题– UriBuilder问题

最近在使用Java Docker来控制Docker的过程中发现了一个问题,因为Java Docker使用的是Jersey 2.x,maven pom如下:

<dependency>
    <groupId>com.github.docker-java</groupId>
    <artifactId>docker-java</artifactId>
    <version>3.0.13</version>
</dependency>

而集群中Hadoop的依赖都是Jersey 1.x。所以在引用的过程中提示如下错误:

Exception in thread "main" java.lang.AbstractMethodError: javax.ws.rs.core.UriBuilder.uri(Ljava/lang/String;)Ljavax/ws/rs/core/UriBuilder;
        at javax.ws.rs.core.UriBuilder.fromUri(UriBuilder.java:119)
        at org.glassfish.jersey.client.JerseyWebTarget.<init>(JerseyWebTarget.java:71)
        at org.glassfish.jersey.client.JerseyClient.target(JerseyClient.java:290)
        at org.glassfish.jersey.client.JerseyClient.target(JerseyClient.java:76)
        at com.github.dockerjava.jaxrs.JerseyDockerCmdExecFactory.init(JerseyDockerCmdExecFactory.java:237)
        at com.github.dockerjava.core.DockerClientImpl.withDockerCmdExecFactory(DockerClientImpl.java:161)
        at com.github.dockerjava.core.DockerClientBuilder.build(DockerClientBuilder.java:45)

很明显这是Jersey版本mismatch导致的,在解决这一过程中,走了不少弯路,包括采用了maven shade plugin来解决,采用exclude一些jar包来解决等,都没有解决问题。
最后还是从错误出发,这个错误的原因是fromUri这个方法是一个抽象方法,没有实现,也就是只有抽象方法,没有实现类。
再把代码看一下,在Jersery 2.x中的实现为:

public abstract UriBuilder uri(String var1);

它的实现类为org.glassfish.jersey.uri.internal.JerseyUriBuilder,看到这一部分,大概了解到原因是缺少了实现类。于是加入相应的dependency到pom中

        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-server</artifactId>
            <version>2.23.1</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet-core</artifactId>
            <version>2.23.1</version>
        </dependency>

加入后再打包,解决这一问题。

Maven-Shade-Plugin 介绍

在我们像集群中提交任务的时候,常常因为app的jar包与Hadoop CLASSPATH中jar包冲突导致了No such method错误等等。
为了解决这一问,采用Maven-shade-plugin,这个插件的主要作用是将打包过程中内部的jar包重新命名为新的名称,防止由于引用不同版本导致的问题,例如:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.0.0</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <relocations>
                <relocation>
                  <pattern>org.codehaus.plexus.util</pattern>
                  <shadedPattern>org.shaded.plexus.util</shadedPattern>
                  <excludes>
                    <exclude>org.codehaus.plexus.util.xml.Xpp3Dom</exclude>
                    <exclude>org.codehaus.plexus.util.xml.pull.*</exclude>
                  </excludes>
                </relocation>
              </relocations>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  ...
</project>

How to solve “.Git Directory Could Not Be Found! Please Specify a Valid [dotGitDirectory] in Your pom.xml” Problem

When i modify the source code of presto, and execute mvn package, something wrong happened, the stack trace is as follow:

.Git Directory Could Not Be Found! Please Specify a Valid [dotGitDirectory] in Your pom.xml

After google the problem, i find a simple way to solve it. Add this plugin to your pom.xml and everything is ok.

            <plugin>
              <groupId>pl.project13.maven</groupId>
              <artifactId>git-commit-id-plugin</artifactId>
              <version>2.1.15</version>
              <configuration>
                <failOnNoGitDirectory>false</failOnNoGitDirectory>
              </configuration>
            </plugin>

Hadoop trunk maven编译问题

 从Hadoop trunk git库中pull下来代码后,需要进行编译,但是编译过程中报以下错误:

[ERROR] Plugin org.apache.hadoop:hadoop-maven-plugins:3.0.0-SNAPSHOT or one of its dependencies could not be resolved: Could not find artifact org.apache.hadoop:hadoop-maven-plugins:jar:3.0.0-SNAPSHOT -> [Help 1]

       解决方法很简单:

       $ cd hadoop-maven-plugins

       $ mvn install

MAVEN org.eclipse.m2e:lifecycle-mapping问题

      最近在编译Presto时候遇到了一个MAVEN的问题,MAVEN报以下错误:

       [WARNING] The POM for org.eclipse.m2e:lifecycle-mapping:jar:1.0.0 is missing, no dependency information available

       [WARNING] Failed to retrieve plugin descriptor for org.eclipse.m2e:lifecycle-mapping:1.0.0: Plugin org.eclipse.m2e:lifecycle-mapping:1.0.0 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.eclipse.m2e:lifecycle-mapping:jar:1.0.0

      google以下,发现了以下的解决方法:

      1、checkout https://github.com/mfriedenhagen/dummy-lifecycle-mapping-plugin

      2、解压,mvn clean install

      3、再去编译自己的工程,okay,解决

Maven加入新的source问题

    最近将之前做的hadoop-raid移植到2.4.0上面,因为之前的RPC都是通过POJO,而现在2.x的RPC都是通过PB(参见我之前写过的Blog),所以需要将新加入的Protocol进行PB的改写。

    其中写好proto文件后,需要用hadoop写好的hadoop-maven-plugin插件将proto文件生成java文件。

 <plugin>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-maven-plugins</artifactId>
        <executions>
          <execution>
            <id>compile-protoc-raid</id>
            <phase>generate-sources</phase>
            <goals>
              <goal>protoc</goal>
            </goals>
            <configuration>
              <protocVersion>${protobuf.version}</protocVersion>
              <protocCommand>${protoc.path}</protocCommand>
              <imports>
                <param>${basedir}/../../hadoop-common-project/hadoop-common/src/main/proto</param>
                <param>${basedir}/src/main/proto</param>
              </imports>
              <source>
                <directory>${basedir}/src/main/proto</directory>
                <includes>
                  <include>RaidProtocol.proto</include>
                </includes>
              </source>
              <output>${project.build.directory}/generated-sources/java</output>
            </configuration>
          </execution>
        </executions>
      </plugin>

    同时需要将生成的java文件加入ClassPath中,采用的是org.codehaus.mojo.build-helper-maven-plugin插件。

      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>build-helper-maven-plugin</artifactId>
        <executions>
          <execution>
            <id>add-raid-generated-sources-directory</id>
            <phase>generate-sources</phase>
            <goals>
              <goal>add-source</goal>
            </goals>
            <configuration>
              <sources>
                <source>${project.build.directory}/generated-sources/java</source>
              </sources>
            </configuration>
          </execution>
        </executions>
      </plugin>

    但是使用后能够在terminal中顺利编译,而eclipse却显示没有加入这个classpath。

    最后想到还是用maven命令生成一遍,mvn clean generate-sources eclipse:eclipse

就解决问题了。

Maven out of memory 解决方法

    有时候使用maven的时候,如果采用默认的jvm参数会报oom错误,这个所有java程序员都知道为什么,那修改方法只要加入maven jvm参数就可以了。方法是在环境变量中,加入以下

    export MAVEN_OPTS=”-Xms1024m -Xmx2000m”