英文:
Error caused on runtime of java class file
问题
我如何在不知道开发者使用的特定包的情况下编译和运行Java文件...
我得到了一个由他人编写的Java文件文件夹,我正在尝试编译和运行这些Java文件,我可以通过运行 javac *.java
来编译这些文件,但是如果我尝试通过调用 java MainClass
来运行主类,我会得到一个错误,像这样:错误:找不到或加载主类 MainClass,原因:java.lang.NoClassDefFoundError: SomePackageName/MainClass(名称错误:MainClass)
我不知道 SomePackageName
是什么,它是由开发者定义的,我无法控制。
所以问题是,如果我只知道主类,我该如何编译和运行这些Java文件?
英文:
How do I compile and run java files if you don't know the specific package used by the developer...
I got a folder of java files written by someone else, and I'm trying to compile and run the java files, I can compile the files by running javac *.java
, but if I try to run the main class by calling java MainClass
, I get an error like so: Error could not find or load main class MainClass, Caused by: java.lang.NoClassDefFoundError: SomePackageName/MainClass (wrong name: MainClass)
I have no idea whats the SomePackageName its defined by the developer and I have no control over that.
so the question is how do I compile and run the java files if all I know is which is the main class?
答案1
得分: 2
- 完全限定类名的格式为:
com.foo.Bar
,其中com.foo
是包名(例如,定义 Bar 类的文件以package com.foo;
开头),而 Bar 是类名(例如,文件包含行public class Bar {
)。 - 在运行
java
并指定类路径+类名时,传递的是类名,而不是文件名。因此,要运行此文件,您会写成java -cp /path/to/base com.foo.Bar
。 - 完全限定名称在运行时(类文件)和编译时(Java 文件)都必须与目录结构匹配。因此,在这里,您应该有类似
/Users/Foghunt/projects/myproj/src/com/foo/Bar.java
的路径,并且编译后应该有类似/Users/Foghunt/projects/myproj/build/com/foo/Bar.class
的路径。 - “基本目录” 是包含第一个包目录的目录。因此,源文件的基本目录是
/Users/Foghunt/projects/myproj/src
,编译结果的基本目录是/Users/Foghunt/projects/myproj/build
。 - 基本目录需要在类路径中。类路径条目是文件路径。因此,要运行这个东西,您会写成
java -cp /Users/Foghunt/projects/myproj/build com.foo.Bar
。 javac
不介意您是否费心正确地定义事物(例如,在/Users/Foghunt/projects/myproj/src/com/foo
中运行javac *.java
是可行的),但如果涉及多个包,情况会很复杂。- 通常情况下,您应该使用构建系统。如果您继承了这个项目,请在项目根目录中检查是否有名为
build.xml
、pom.xml
或build.gradle
的文件。如果存在这些文件之一,请使用网络搜索引擎(build.xml
-> 搜索java ant
,pom.xml
-> 搜索java maven
,build.gradle
-> 搜索java gradle
),并使用它来构建项目,不要自行运行javac
。
有了这些知识,您现在可以分析、构建和运行任何 Java 项目了。
英文:
- Fully qualified class names are of the form:
com.foo.Bar
, wherecom.foo
is the package (e.g. the file defining the Bar class starts with the linepackage com.foo;
), and Bar is the name (e.g. the file contains the linepublic class Bar {
). - When running
java
and specifying classpath+classname, you pass a class name. Not a file name. So to run this file you'd writejava -cp /path/to/base com.foo.Bar
. - fully qualified names must match directory structure both at runtime (class files) and compile time (java files). So, here you should have say
/Users/Foghunt/projects/myproj/src/com/foo/Bar.java
and after compilation you should have e.g./Users/Foghunt/projects/myproj/build/com/foo/Bar.class
- The 'base dir' is the one that contains the first package directory. So, the base dir for the source file is
/Users/Foghunt/projects/myproj/src
and for the compiled result is/Users/Foghunt/projects/myproj/build
. - The base dir needs to be in the classpath. Classpath entries are file paths. So, to run this thing you'd write
java -cp /Users/Foghunt/projects/myproj/build com.foo.Bar
. javac
doesn't mind if you don't go through the trouble of properly defining things (e.g. runningjavac *.java
in/Users/Foghunt/projects/myproj/src/com/foo
does work), but it gets complicated quickly if you have multiple packages.- In general you should be using build systems. If you've inherited this project, check for a file named
build.xml
orpom.xml
orbuild.gradle
in the root of the project. If it is there, use a web search engine (build.xml
-> search forjava ant
,pom.xml
->java maven
,build.gradle
->java gradle
), and use that to build the project, don't runjavac
yourself.
There you go. Armed with that knowledge you can now analyse, build, and run any java project.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论