錯(cuò)誤描述
javac helloworld.java能夠通過。但是java helloworld出現(xiàn)錯(cuò)誤:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
hadoop @xuwei -erplab:~/jarfile$ java HelloWorld Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld (wrong name: org/xuwei/HelloWorld) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(ClassLoader.java: 631 ) at java.lang.ClassLoader.defineClass(ClassLoader.java: 615 ) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java: 141 ) at java.net.URLClassLoader.defineClass(URLClassLoader.java: 283 ) at java.net.URLClassLoader.access$ 000 (URLClassLoader.java: 58 ) at java.net.URLClassLoader$ 1 .run(URLClassLoader.java: 197 ) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java: 190 ) at java.lang.ClassLoader.loadClass(ClassLoader.java: 306 ) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java: 301 ) at java.lang.ClassLoader.loadClass(ClassLoader.java: 247 ) Could not find the main class : HelloWorld. Program will exit. |
2、問題解決
在文獻(xiàn)1中很多人提到都是因?yàn)榄h(huán)境變量classpath配置錯(cuò)誤。說(shuō)是沒有加上當(dāng)前路徑"."。但是我查看了自己的classpath為
export CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$CLASSPATH
這表明我的classpath配置是正確的。這個(gè)時(shí)候我找到了文獻(xiàn)2,里面提到了helloword分為帶包名和不帶包名兩類。
3、不含包層次的HelloWorld.java
1
2
3
4
5
|
public class HelloWorld { public static void main(String args[]){ System.out.println( "Hello World!" ); } } |
保存在/home/hadoop/jarfile下,使用javac命令編譯:
$ javac HelloWorld.java
運(yùn)行:
$ java HelloWorld
屏幕打印出:
Hello World!
4、初學(xué)者常犯的錯(cuò)誤
4.1. 運(yùn)行時(shí),帶了.class后綴
如果你試圖使用如下命令:(下面的命令都是假設(shè)在HelloWorld.java所在目錄執(zhí)行,即/home/hadoop/jarfile)
java HelloWorld.class
系統(tǒng)會(huì)誤認(rèn)為你運(yùn)行的是HelloWorld包下的名為class的類文件,會(huì)到系統(tǒng)的CLASSPATH下(一般都包括當(dāng)前目錄)企圖尋找 HelloWorld.class.class這樣的類,這樣的類當(dāng)然不存在了;并且也不可能存在,因?yàn)閏lass是關(guān)鍵字,不能作為一個(gè)類的名字。所以會(huì)報(bào)如下錯(cuò)誤信息:
Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld/class
4.2. 文件名大小寫錯(cuò)誤
對(duì)于像Windows這樣的系統(tǒng),編譯時(shí)可以不關(guān)心大小寫(linux區(qū)分大小寫)。比如編譯HelloWorld.java時(shí),也可以使用:
javac helloworld.java
也可以編譯通過,但產(chǎn)生的類文件仍然是和源文件相符的:HelloWorld.class。但在運(yùn)行時(shí)一定要注意大小寫,比如試圖使用如下命令運(yùn)行:
java helloworld
將報(bào)類似于1中的錯(cuò)誤:
Exception in thread "main" java.lang.NoClassDefFoundError: helloworld (wrong name: HelloWorld)
5、包含包層次的HelloWorld.java
比如上面的HelloWorld.java修改如下:
1
2
3
4
5
6
7
|
package org.myorg; public class HelloWorld { public static void main(String args[]){ System.out.println( "Hello World!" ); } } |
編譯時(shí)有兩種方法
5.1. 直接編譯
javac HelloWorld.java
此時(shí)在當(dāng)前目錄下輸出HelloWorld.class。此時(shí),運(yùn)行不能使用上面相同的方法,使用:
java HelloWorld
運(yùn)行時(shí),出現(xiàn)如下錯(cuò)誤:
Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld (wrong name: org/myorg/HelloWorld)
從上述錯(cuò)誤信息你也可以看到,系統(tǒng)可以找到HelloWorld類(因?yàn)楫?dāng)前路徑包含在CLASSPATH中,具體為什么會(huì)提示wrong name,有興趣的朋友參見Java語(yǔ)言規(guī)范),但這個(gè)類屬于org.myogr包。所以,你要做的就是按照上述包層次,相應(yīng)的創(chuàng)建目錄層次,把上面生成的HelloWorld.class放到/home/hadoop/jarfile/org/myorg目錄下。HelloWorld.java在/home/hadoop/jarfile/目錄下。運(yùn)行:
java org.myorg.HelloWorld
系統(tǒng)打印出:
Hello World!
這兒要注意的是,不能使用java org\myorg\HelloWorld來(lái)運(yùn)行,此時(shí)同樣會(huì)出現(xiàn)如下錯(cuò)誤:
Exception in thread "main" java.lang.NoClassDefFoundError :org\myorg\HelloWorld (wrong name: org\myorg\HelloWorld)
是不是有點(diǎn)怪怪的,那沒辦法。以后對(duì)Java的包有更深的認(rèn)識(shí)時(shí),就會(huì)明白了。
5.2. 使用 -d <directory>編譯選項(xiàng)
是不是覺得上面的編譯方法有點(diǎn)麻煩,能不能自動(dòng)在當(dāng)前路徑(或任意指定的路徑)下生成包層次呢?有!使用-d <directory>編譯選項(xiàng)就能做到。
javac -d . HelloWorld.java
此時(shí),在當(dāng)前目錄(/home/hadoop/jarfile)下就生成了一個(gè)org\myorg目錄(/home/hadoop/jarfile/org/myorg),并且輸出的.class文件也在里面。運(yùn)行:
java org.myorg.HelloWorld
系統(tǒng)打印:
Hello World!
如果你想把生成的類文件集中存放在一個(gè)目錄中,比如:/home/hadoop/jarfile/test下,那么你首先創(chuàng)建這個(gè)目錄,然后編譯時(shí):
javac -d /home/hadoop/jarfile/test HelloWorld.java
就可以把生成的類文件放到/home/hadoop/jarfile/test目錄下,并且按照包層次相應(yīng)的創(chuàng)建目錄路徑。你可以在/home/hadoop/jarfile/test/org/myorg下找到HelloWorld.class文件。此時(shí)使用如下命令可以正確運(yùn)行(注意如果要用到其它類,請(qǐng)?jiān)贑LASSPATH中設(shè)好):
hadoop@xuwei-erplab:~/jarfile/test$ java org.xuwei2.HelloWorld
注意上述命令是在/home/hadoop/jarfile/test下執(zhí)行的。
如果不行可以參考下面的方法:
第二個(gè)問題解決方法:
這是因?yàn)镴DK的版本而產(chǎn)生的問題,我裝的是OpenJDK,會(huì)出現(xiàn)JAR包的缺失,導(dǎo)致啟動(dòng)報(bào)錯(cuò),所以這里需要更換為Oracle官方給出的JDK
1、去Oracle官方下載一個(gè)這樣的包:jdk-7u79-linux-x64.tar.gz
2、解壓之后,移動(dòng)到/usr/local/java目錄下
3、添加環(huán)境變量:vim /etc/profile,文件最后添加下面幾行
export JAVA_HOME=/usr/local/java/jdk1.7.0_79 //實(shí)際的JDK路徑
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
4、完成上述安裝之后,再啟動(dòng)Tomcat,發(fā)現(xiàn)還會(huì)報(bào)錯(cuò):Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
這個(gè)問題是因?yàn)門omcat沒有識(shí)別出JDK的環(huán)境變量
5、修改Tomcat中bin目錄的catalina.sh文件,在文件的開頭,加入下面代碼:
export JAVA_HOME=/usr/local/java/jdk1.7.0_79 ////實(shí)際的JDK路徑
export JRE_HOME=/usr/local/java/jdk1.7.0_79/jre
最后啟動(dòng)Tomcat,日志打印正常,瀏覽器也能夠訪問,問題解決
Exception in thread "main" java.lang.InternalError
at sun.security.ec.SunEC.initialize(Native Method)
at sun.security.ec.SunEC.access$000(SunEC.java:49)
at sun.security.ec.SunEC$1.run(SunEC.java:61)