【问题标题】:How does maven find Java compiler?maven如何找到Java编译器?
【发布时间】:2014-08-28 05:36:01
【问题描述】:

我是按照 sonatype 的书给出的这个例子学习 maven 的新手。这是一个最简单的 pom.xml 文件(工作正常)。但我的问题是,maven (mvn install) 如何找到安装在我机器上的 Java 编译器 (javac)?这个 POM 文件没有以任何方式指定 JDK。谢谢解释。

编辑: 作为比较,我按照书中的下一个示例进行操作,这一次,我收到了一个编译错误,因为它找不到 javax。我的 java 文件在其中,正如书中建议的那样:src/main/java/org/sonatype/mavenbook/web/SimpleServlet.java

现在当我运行 mvn compile 时,我在下面收到错误消息。为什么现在maven找不到编译器:

ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project simple-webapp: Compilation failure: Compilation failure:
[ERROR] /home/abigail/study/simple-webapp/src/main/java/org/sonatype/mavenbook/web/SimpleServlet.java:[4,1] package javax.servlet does not exist

POM.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                         http://maven.apache.org/maven-    v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.mavenbook.simpleweb</groupId>
<artifactId>simple-webapp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>simple-webapp Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>
</dependencies>
<build>
    <finalName>simple-webapp</finalName>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
    </plugins>
</build>
</project>

【问题讨论】:

  • 我确实设置了这个变量,但不确定它是否重要。

标签: java maven


【解决方案1】:

如果你走这条路,说maven version 3.2.3

apache-maven-3.2.3-bin\apache-maven-3.2.3\bin

打开mvn.bat,可以在下面看到

@REM Maven2 启动批处理脚本

@REM 必需的 ENV 变量:

@REM JAVA_HOME - JDK 主目录的位置

很明显,它会从您的环境变量中选择JAVA_HOME。下面是文件中的代码 sn-p。

@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto chkMHome
:chkMHome
if not "%M2_HOME%"=="" goto valMHome

问题,javax.servlet

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>

或任何可用的

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
</dependency>

【讨论】:

  • 是的,我看到了。谢谢。你能弄清楚为什么我上面的例子 maven 找不到 javax 吗?
  • 谢谢。为什么必须将 servlet 作为依赖项包含在内?它也是 JDK 标准包的一部分。
  • 不,它不是 - 它是 JEE 的一部分。
【解决方案2】:

Maven 使用环境变量JAVA_HOME 来查找JDK。

【讨论】:

    【解决方案3】:

    由于 maven 本身是一个 java 应用程序,它只会默认为运行 maven 目标的 jdk。

    要获得更多编译选项,您必须使用:

    http://maven.apache.org/plugins/maven-compiler-plugin/

    也看看这个:

    http://maven.apache.org/plugins/maven-compiler-plugin/examples/compile-using-different-jdk.html

    编辑:

    对于您的后续问题: 如果您查看 mvn 可执行文件(默认情况下位于:/usr/bin/mvn),您会发现它是一个相当冗长的 bash 脚本,需要花费大量时间来查找 jdk 的位置。当然,你可以设置 JAVA_HOME 系统属性并“帮助”脚本,但即使你没有它,它也会尝试找到它,只有当它失败时,它才会出现错误。

    从 /usr/bin/mvn:

    if [ -z "$JAVA_HOME" ]; then
      javaExecutable="`which javac`"
      if [ -n "$javaExecutable" -a ! "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
        # readlink(1) is not available as standard on Solaris 10.
        readLink=`which readlink`
        if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
          javaExecutable="`readlink -f \"$javaExecutable\"`"
          javaHome="`dirname \"$javaExecutable\"`"
          javaHome=`expr "$javaHome" : '\(.*\)/bin'`
          JAVA_HOME="$javaHome"
          export JAVA_HOME
        fi
      fi
    

    if [ -z "$JAVACMD" ] ; then
      if [ -n "$JAVA_HOME"  ] ; then
        if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
          # IBM's JDK on AIX uses strange locations for the executables
          JAVACMD="$JAVA_HOME/jre/sh/java"
        else
          JAVACMD="$JAVA_HOME/bin/java"
        fi
      else
        JAVACMD="`which java`"
      fi
    fi
    

    实际上,脚本的大部分代码都与确定使用哪个 java 以及该 java 所在的位置有关。 但是,一旦您运行 mvn 可执行文件,不会限制它使用与它本身一起运行的相同 jdk 进行编译/运行。这里是 mvn 编译器插件发挥作用的地方,您可以在其中指定要使用的其他 jdk 安装。

    【讨论】:

    • 默认使用哪个 JDK 运行 maven 目标?是不是因为JDK安装在/usr/bin/目录下所以maven可以直接访问,不需要任何其他规范?
    • 请注意:我发现 Maven 查找 JDK(是 JDK,不是 JRE)的方法有一点缺陷。 JAVA_HOME 环境变量最初用于 JRE 位置,因此它可能指向您机器上的 JRE 位置,不是因为 Maven,而是因为该主机上的其他应用程序。因此,您可能需要有一个围绕 mvn.bat|sh 的包装器来适当地设置 JAVA_HOME 环境变量。 +1 提及 maven-compiler-plugin 设置。
    【解决方案4】:

    所以我只是让 maven 从我的默认位置选择不同的 Java 位置:

    Java8

    [tomek:~] $ java -version
    java version "1.8.0_144"
    Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
    Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)
    

    但是 maven 选择了 Java9

    [tomek:~] $ mvn -version
    Apache Maven 3.3.9
    Maven home: /usr/share/maven
    Java version: 9-internal, vendor: Oracle Corporation
    Java home: /usr/lib/jvm/java-9-openjdk-amd64
    

    JAVA_HOME 未设置:

    [tomek:~] $ echo "Java HOME: $JAVA_HOME"
    Java HOME:
    

    所以我怀疑它只是在 ubuntu 上带来了第一个替代方案(忽略用户的选择):

    [tomek:~] $ sudo update-alternatives --config java
    There are 3 choices for the alternative java (providing /usr/bin/java).
    
    Selection    Path                                            Priority   
    Status
    ------------------------------------------------------------
     0            /usr/lib/jvm/java-9-openjdk-amd64/bin/java       1091       auto mode
     * 1            /opt/java/jdk1.8.0_144/bin/java                  1         manual mode
       2            /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java   1081      manual mode
      3            /usr/lib/jvm/java-9-openjdk-amd64/bin/java       1091      manual mode
    

    【讨论】:

      猜你喜欢
      • 2019-01-24
      • 1970-01-01
      • 2019-05-31
      • 1970-01-01
      • 2013-11-20
      • 2012-12-19
      • 2012-10-21
      • 2016-11-11
      • 1970-01-01
      相关资源
      最近更新 更多