爲何你的程序配了classpath仍是找不到類

classpath簡介

classpath是java程序時擁有的一個系統變量,這個變量能夠經過以下方式獲取html

System.out.println(System.getProperty("java.class.path"));

爲何classpath設置了就是找不到類

1.首先,classpath只和應用程序類加載器有關,若是發生了class not found exception,首先確認是否異常出自哪一個類加載器,出自哪一個類加載器說明jvm使用哪一個類加載器嘗試加載的java

java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

如以上異常棧說明異常出自應用程序類加載器linux

2.當確認來自應用程序類加載器,須要確認classpath中是否包含目標類。
關於classpath的說明能夠參考官方文檔,https://docs.oracle.com/javase/8/docs/technotes/tools/windows/classpath.html
個人經驗總結是:若是目標類文件在某個目錄中,classpath應該包含這個目錄,若是目標類在某個目錄的某個jar包中或是zip包中,好比c.jar存在my_jars目錄下,那麼classpath應該包含my_jars/c.jar或是jars/*,若是僅含有my_jars,是不會從目錄下的jar包加載類的windows

3.正確設置classpath的方式
1.目標類是存在.class文件中,將其所在目錄的添加到classpath,這裏須要注意目錄和包名對應。
2.目標類是存在jar包文件中,將該jar包的文件名或是所在目錄+"/*"添加到classpath
3.目錄+"/ *"只對從jar/zip包中加載有效,若是要某個目錄下的.class文件中加載類,使用目錄+"/ *"的方式,加載器會拋class not found異常。oracle

classpath與類加載器的關係

咱們都知道classpath與類加載有關,這究竟體如今哪裏呢?咱們知道在java中類加載的工做是經過類加載器完成的,當jvm啓動後,除了自帶的內建類加載器外,還會建立一個擴展類加載器和應用程序類加載器,這個過程在sun.misc.Launcher源碼中有體現。當應用程序類加載器建立好後,會做爲系統默認的類加載器,具體在 類加載器文中詳細說明。
這個類加載器會讀取這個系統變量,並將其做爲查找路徑。jvm

public static ClassLoader getAppClassLoader(final ClassLoader var0) throws IOException {
            final String var1 = System.getProperty("java.class.path");
            final File[] var2 = var1 == null ? new File[0] : Launcher.getClassPath(var1);
            return (ClassLoader)AccessController.doPrivileged(new PrivilegedAction<Launcher.AppClassLoader>() {
                public Launcher.AppClassLoader run() {
                    URL[] var1x = var1 == null ? new URL[0] : Launcher.pathToURLs(var2);
                    return new Launcher.AppClassLoader(var1x, var0);
                }
            });
        }

如何設置變量

  1. 執行java時指定 -cp參數
  2. 未指定-cp參數時,java會讀取環境變量,這個變量的設置方式和操做系統有關,在linux/unix環境下,經過export CLASSPATH="xxx"方式能夠執行,若是操做系統中沒有配置這個環境變量,則默認爲".",即當前目錄。
    經過man java驗證
相關文章
相關標籤/搜索