Java无法找到主类,即使主类存在。

huangapple go评论59阅读模式
英文:

Java cannot find main class even though main class is present

问题

我一直在尝试运行一个 JAR 文件,但是一直收到以下错误提示:

错误:找不到或加载不了主类 com.myclass
原因:java.lang.ClassNotFoundException: com.myclass

这非常令人困惑,因为我已经解压了 JAR 文件,而且类位于正确的位置。以下是我使用 Gradle 编译 JAR 的方法:

jar {
  manifest {
    attributes 'Main-Class': 'com.myclass'
  }

  from {
    configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
  }
}

我认为这可能是 Java 的问题,因为 JAR 文件似乎是正确的。是否有人知道我该如何解决这个问题?

英文:

I've been trying to run a jar but I keep getting the error:

Error: Could not find or load main class com.myclass
Caused by: java.lang.ClassNotFoundException: com.myclass

This is very confusing because I extracted the jar and the class was present in the proper location. This is how I compiled the jar using gradle:

jar {
  manifest {
    attributes 'Main-Class': 'com.myclass'
  }

  from {
    configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
  }
}

I believe it is a problem with java since the jar file seems to be correct. Does anyone know how I could fix this?

答案1

得分: 1

你的问题没有包含任何直接指示你做错了什么的细节。

但是我可以告诉你一般的原则:

解压那个jar文件(它是一个zip文件,所以任何解压工具都可以。或者在一个新创建的目录中运行jar xvf myjar.jar也可以完成任务)。

在其中,至少应该有两个文件,位于以下精确位置:

  • com/foo/MyClass.class
  • META-INF/MANIFEST.MF

然后,用记事本打开清单文件或者从终端中使用cat命令查看它。它应该包含这一行,同样地,精确

  • Main-Class: com.foo.MyClass

如果这些条件都成立,但你在这个问题中报告的错误仍然发生,那么我们就遇到了真正奇特的问题,比如损坏的虚拟机或损坏的类文件。更可能的是你在阅读某些内容时出现了误解,仔细检查名称。

注意:如果你忘记为你的类添加一个正确签名的“main”方法,错误会有所不同,因此问题不在这里。

就它的价值而言,这部分内容:

   from {
     configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
   }

看起来不太标准。你是否有特定的目标要在你的Gradle构建文件中实现,而这些目标并不是默认内置的?如果是这样,你可能做错了什么;你可以在Stack Overflow上提一个关于这个问题的专门问题,特别是要将这部分内容(尤其是你在清单中发现的内容,以及类文件实际在jar文件中的位置)作为那个问题的附注。

英文:

Your question does not include any details that would directly indicate what you've done wrong.

But I can tell you the general principle:

Unpack that jar (it's a zip file, so any unzipper will do. Alternatively, jar xvf myjar.jar in a freshly created directory will also do the job).

In it, there should be at least 2 files, at these exact locations:

  • com/foo/MyClass.class
  • META-INF/MANIFEST.MF

Then, open the manifest file with notepad or cat it from the terminal. It should contain this line, again, exactly:

  • Main-Class: com.foo.MyClass

If these things are all true, and yet the error you reported in this question is occurring, we've arrived at truly exotic stuff, such as corrupt VMs or corrupt class files. More likely you're misreading something, double check the names.

NB: If you forget to add a properly signatured 'main' method to your class, the error is different, hence, that isn't it.

For what it is worth, this section:

   from {
     configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
   }

looks non-standard. Is there any particular thing you're trying to make your gradle build file do that isn't already built into the defaults? In which case, you may be doing that wrong; you may want to ask another SO question specifically about that, and include this part (in particular, your findings about what's in that manifest and where the class file is actually inside your jar file) as a footnote to that question.

答案2

得分: 0

包是强制性的。未命名包中的内容(这是在类没有包语句的情况下发生的情况)实际上仍然在一个包中,但这是一个无法命名的包。唯一的例外是当运行 java -cp classpath;here myclass 时,这种方式的例外情况确实起作用。关键是,在任何清单属性中都不起作用,您无法导入它们,并且它们不适用于 module-info 文件(即无论在哪里出现类名,未命名包中的类名都不能被引用)。

因此,请添加一个包语句并将内容移动到与其匹配的子目录中。

英文:

Packages are mandatory. Things in the unnamed package (which is what happens when classes don't have a package statement) effectively are still in a package, but it is a package you can't type. The only exception is when running java -cp classpath;here myclass which by way of exception does work. The point is, it doesn't work in any manifest attribute, you can't import them at all, and they don't work in module-info files (i.e., everywhere else class names come up, classes in the unnamed package simply cannot be referred to).

So, add a package statement and move things in subdirs that match this.

答案3

得分: 0

通常情况下,当您使用Eclipse IDE时,编译器会在包名处报告此错误。尝试将包含main方法的类打包到特定的包中。

英文:

Usually compiler throws this error with the package name as well, when you are using Eclipse IDE.
Try packing the class with main method inside the specific package.

huangapple
  • 本文由 发表于 2020年9月13日 23:07:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/63872278.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定