java从命令行编译

时间:2013-09-28 16:34:49

标签: java javac importerror

我是一名经验丰富的程序员,但多年来一直没有使用Java - 主要是C# - 并且过去使用过IDE。我正在尝试从我的Mac上的命令行编译一些代码,但无法获取我的测试文件来查找我的源代码。我假设问题出在包,文件结构,类路径和导入语句空间的某个地方 - 但我已经花了几个小时(包括在Stack Overflow上搜索)并且仍然卡住了。

这就是我所拥有的:

Directory structure:
ProjectName
|
 --src
    |
     --SourceClass
 --test
    |
     --SourceClassTest
 --external
    |
     --testng-6.8.7.jar

我的SourceClass看起来像这样:

package ProjectName;

public class SourceClass<T>{

}

很简单。显然,会有更多 - 但我想首先确保在实际编码之前我已经完成了所有这些设置。

我的测试类看起来像这样:

package ProjectName;

import java.util.*;
import org.testng.Assert;
import org.testng.annotations.*;


    public class SourceClassTest{

            @Test
            private void createEmptySourceClass(){
                    SourceClass<Object> sourceClass = new SourceClass<Object>();
                    Assert.assertTrue(sourceClass.isEmtpy());
            }

    }

sourceClass编译时没有“javac src / * .java”的问题,从“ProjectName”目录运行。我希望看到这个失败,并出现“SourceClass没有isEmpty()方法”的错误,但我从“ProjectName”目录运行这样的javac:

javac test/*.java -classpath external/testng-6.8.7.jar

并获得此例外:

test/SourceClassTest.java:12: error: cannot find symbol
        SourceClass<Object> tree = new SourceClass<Object>();
        ^
  symbol:   class SourceClass
  location: class SourceClassTest
test/SourceClassTest.java:12: error: cannot find symbol
        SourceClass<Object> sourceClass = new SourceClass<Object>();
                                       ^
  symbol:   class SourceClass
  location: class SourceClassTest
2 errors

我尝试过很多东西 - 添加一个import语句,在javac命令中添加一个源路径,将sourceClass编译为jar并将其放入bin目录然后将其添加到类路径中,但我不能得到测试以找到SourceClass符号。

知道我在这里缺少什么吗?

3 个答案:

答案 0 :(得分:2)

如果您编译到单独的目标目录中,它将起作用。 E.g,

mkdir target
javac -d target/ src/*.java
javac -classpath target/ test/*.java

执行javac src/*.java时,它会在.class目录中创建src文件。默认情况下,您引用的任何类都假定在同一个包中。因此,即使您将src/添加到类路径,它也会查找它找不到的src/ProjectName/SourceClass.class。当您传递-d target/选项时,它会创建正确的包层次结构,因此会找到该类。

javac official doc的相关文档:

  

您应该将源文件排列在反映的目录树中   他们的包树。例如,如果您保留所有源文件   C:\ workspace,com.mysoft.mypack.MyClass的源代码应该是   在C:\ workspace \ com \ mysoft \ mypack \ MyClass.java。

     

默认情况下,编译器将每个类文件放在同一目录中   它的源文件。您可以使用指定单独的目标目录   -d(参见下面的选项)。

     

...

     

...

     

-d 目录设置类文件的目标目录。该目录必须已存在; javac不会创建它。如果是一个班级   作为包的一部分,javac将类文件放在子目录中   反映包名称,根据需要创建目录。对于   例如,如果指定-d C:\ myclasses并调用该类   com.mypackage.MyClass,然后调用类文件   C:\ myclasses \ COM \ mypackage中\ MyClass.class。如果未指定-d,   javac将每个类文件放在与源文件相同的目录中   从中生成。

     

注意:-d指定的目录不会自动添加到您的   用户类路径。

答案 1 :(得分:1)

我的猜测是它无法找到SourceClass,因为定义该类的文件位于src下,并且您没有在javac命令行中提及该目录。

如果我是你,我会将文件层次结构更改为:

ProjectName/src/ProjectName/SourceClass.java
ProjectName/src/ProjectName/SourceClassTest.java
ProjectName/external/testng-6.8.7.jar

然后运行javac src/ProjectName/*.java -classpath external/testng-6.8.7.jar

或保持文件层次结构的方式,并运行javac src/*.java test/*.java -classpath external/testng-6.8.7.jar

答案 2 :(得分:0)

可接受的答案是正确的,但是它遗漏了一个关键点:当要求javac编译*.java(而不是foo.java然后是foo2.java ...)时,它会处理它们作为一个单独的包,并接受它们之间的引用。

那是魔术。其他语言对头文件的隐式处理较少。

即使在阅读了这篇文章之后,我还是花了一些时间才弄清楚,与我固有的假设相反,一个程序在文件上一个接一个地运行将产生(应该)产生与在一组磁盘上运行该程序相同的结果。文件。我的错; *不仅是方便,而且很重要。