【问题标题】:Why if I try to execute a class containing the main() method from within its package I obtain an error message?为什么如果我尝试从其包中执行包含 main() 方法的类,我会收到一条错误消息?
【发布时间】:2015-02-13 02:24:13
【问题描述】:

我有一个 Main 类,其中包含声明到名为 ma​​inPkg 的包中的 ma​​in() 方法。

现在我使用一个 ANT 脚本来执行 Javac 的编译,这个目标:

<target name="compile" depends="clean">

    <mkdir dir="build/classes"/>

    <echo>INTO compile TASK</echo>
    <echo>BASE DIR: ${basedir}</echo>
    <echo>CLASSPATH: ${basedir}\lib\ojdbc6.jar</echo>

    <javac srcdir="src/mainPkg/" destdir="build/classes">

        <classpath>
            <fileset refid="classpath.compile"/>
        </classpath>

    </javac>
</target>

好的,它会在这个目录(位于项目根目录)内创建编译后的 Main.class 文件:build/classes/mainPkg/(最后一个目录有包名)

好的,现在我的疑问是:为什么如果我进入 build/classes/ 文件夹并在这里执行:

java mainPkg.Main

它有效,事实上我获得了这个输出(在某些时候有一个例外,但这是另一个与我此时要求无关的问题):

C:\Projects\edi-sta\build\classes>java mainPkg.Main
Hello World !!!
0
java.lang.ClassNotFoundException: oracle.jdbc.OracleDriver
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        at mainPkg.Main.main(Unknown Source)

但是如果我进入 build/classes/mainPkg/ 目录(包)它不起作用并且我得到一个“无法找到或加载主类” strong> 错误信息?

事实:

 Directory di C:\Projects\edi-sta\build\classes\mainPkg

12/02/2015  17:39    <DIR>          .
12/02/2015  17:39    <DIR>          ..
12/02/2015  17:39             1.190 Main.class
               1 File          1.190 byte
               2 Directory   8.091.906.048 byte disponibili

C:\Projects\edi-sta\build\classes\mainPkg>java Main
Errore: impossibile trovare o caricare la classe principale Main

你能解释一下为什么会这样吗?

Tnx

【问题讨论】:

标签: java jakarta-ee ant jvm javac


【解决方案1】:

如果您在源文件中注意到,Main.java 有一个这样的包语句

package mainPkg;
public class Main{

}

在编译时,您是在说我的 Main 类有一个名为 mainPkg 的命名空间。现在您已经为您的类定义了一个命名空间,任何访问 Main 的尝试都应该具有像 mainPkg.Main 这样的命名空间前缀,我们通常将其称为完全限定类名称。

当您在 build/classes 并调用 java mainPkg.Main 时,JVM 将首先检查当前目录中是否有 mainPkg 子文件夹。因为它已经在那里,它进入并找到Main,验证完全限定的类名是否与我们在 java 命令中给出的匹配,如果相同,它将加载你的类并执行你的 main()。

当您从 build/classes/mainPkg 运行相同的 java mainPkg.Main 时,此时 mainPkg 中没有名为 mainPkg 的子文件夹,因此它会抛出您所看到的错误。

希望这是有道理的:)

【讨论】:

    【解决方案2】:

    它有效,事实上我获得了这个输出(在某些时候有一个 例外,但这是另一个与我要问的问题无关的问题 此时):

    虽然这不是您的问题的目标,但发生异常是因为 oracle 驱动程序 jar 文件不在类路径中。要修复错误,请使用 -cp 选项将 jar 文件 ojdbc6.jar 添加到类路径中。

    但是如果我进入 build/classes/mainPkg/ 目录(包) 它不起作用,我得到一个“无法找到或加载主类” 错误信息?

    mainPkg.Main 是您的 java 类的完全限定名。您需要将其提供给 java 运行时环境,以便它可以找到并运行该类。仅Main 是不够的,因为类路径中可能有许多类名为Main 的java 文件。

    更多信息请访问documentation

    默认情况下,第一个不带选项的参数是 要调用的类。应使用完全限定的类名。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-03
      相关资源
      最近更新 更多