在服務器上部署嵌入式 Tocmat 時, 發現了 java.lang.NoClassDefFoundError
異常 org.ietf.jgss.GSSException
:java
Exception in thread "main" java.lang.NoClassDefFoundError: org/ietf/jgss/GSSException at org.apache.catalina.startup.Tomcat.initSimpleAuth(Tomcat.java:602) at org.apache.catalina.startup.Tomcat.getEngine(Tomcat.java:473) at org.apache.catalina.startup.Tomcat.getHost(Tomcat.java:444) at org.apache.catalina.startup.Tomcat.addContext(Tomcat.java:240) at develon.java.EmbeddedTomcat.init(EmbeddedTomcat.kt:38) at develon.java.EmbeddedTomcatKt.main(EmbeddedTomcat.kt:76) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.jetbrains.kotlin.runner.AbstractRunner.run(runners.kt:61) at org.jetbrains.kotlin.runner.Main.run(Main.kt:110) at org.jetbrains.kotlin.runner.Main.main(Main.kt:120) Caused by: java.lang.ClassNotFoundException: org.ietf.jgss.GSSException at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ... 13 more
通過 locate 排查, 發現 Kotlin 彷佛是徹底有本身的一副運行時類庫, 因此仍是存在必定程度的不兼容nginx
/snap/kotlin/38/lib/kotlin-reflect-sources.jar /snap/kotlin/38/lib/kotlin-reflect.jar /snap/kotlin/38/lib/kotlin-runner.jar /snap/kotlin/38/lib/kotlin-script-runtime-sources.jar /snap/kotlin/38/lib/kotlin-script-runtime.jar /snap/kotlin/38/lib/kotlin-scripting-common.jar /snap/kotlin/38/lib/kotlin-scripting-compiler-impl.jar /snap/kotlin/38/lib/kotlin-scripting-compiler.jar /snap/kotlin/38/lib/kotlin-scripting-jvm.jar /snap/kotlin/38/lib/kotlin-source-sections-compiler-plugin.jar /snap/kotlin/38/lib/kotlin-stdlib-jdk7-sources.jar /snap/kotlin/38/lib/kotlin-stdlib-jdk7.jar /snap/kotlin/38/lib/kotlin-stdlib-jdk8-sources.jar /snap/kotlin/38/lib/kotlin-stdlib-jdk8.jar /snap/kotlin/38/lib/kotlin-stdlib-js-sources.jar /snap/kotlin/38/lib/kotlin-stdlib-js.jar /snap/kotlin/38/lib/kotlin-stdlib-sources.jar /snap/kotlin/38/lib/kotlin-stdlib.jar
那隻好用 Java 運行了, Kotlin 的基本類庫都是哪些呢?git
kotlin-stdlib.jar kotlin-reflect.jar kotlin-script-runtime.jar
在個人 Ubuntu 上github
/snap/kotlin/38/lib/kotlin-stdlib.jar /snap/kotlin/38/lib/kotlin-reflect.jar
這些就足以令個人 Tomcat 跑起來了web
root@iZfi4626828hfcZ:~/Kotlin# java -cp 'nginx.jar:tomcat-embed-core-7.0.52.jar:tomcat-embed-logging-juli-7.0.52.jar:tomcat-annotations-api-7.0.52.jar:/snap/kotlin/38/lib/kotlin-reflect.jar:/snap/kotlin/38/lib/kotlin-stdlib.jar' develon.java.EmbeddedTomcatKt 請輸入主目錄 工做目錄: /root/Kotlin/. 啓用 Spring Sep 29, 2019 8:00:06 PM org.apache.coyote.AbstractProtocol init INFO: Initializing ProtocolHandler ["http-bio-80"] Sep 29, 2019 8:00:07 PM org.apache.catalina.core.StandardService startInternal INFO: Starting service Tomcat Sep 29, 2019 8:00:07 PM org.apache.catalina.core.StandardEngine startInternal INFO: Starting Servlet Engine: Apache Tomcat/7.0.52 開始注射 DispatcherServlet -> STARTING_PREP 注射失敗: org/springframework/web/servlet/support/AbstractAnnotationConfigDispatcherServletInitializer Sep 29, 2019 8:00:07 PM org.apache.catalina.loader.WebappLoader buildClassPath INFO: Unknown loader jdk.internal.loader.ClassLoaders$AppClassLoader@8bcc55f class jdk.internal.loader.ClassLoaders$AppClassLoader 開始注射 DispatcherServlet -> STARTING_PREP 注射失敗: org/springframework/web/servlet/support/AbstractAnnotationConfigDispatcherServletInitializer
Kotlin 提供了一個符號連接 /snap/kotlin/current, 那咱們必須寫一個腳本spring
#!/bin/bash kotlin='/snap/kotlin/current/lib' argc="$#" CLASSPATH='.' if (($argc<1)); then echo \ "jk -cp ./target.jar -cp 'tomcat/lib/*spring*.jar' <Class> [參數列表...] 使用Java運行時運行Kotlin編譯的類, 添加了Kotlin運行時 經過-cp 'classpath'來附加類路徑, 通配符要用單引號''包裝起來造成獨立的參數 " exit 0 fi function startJava() { CLASSPATH="$CLASSPATH:$kotlin/kotlin-stdlib.jar:$kotlin/kotlin-reflect.jar" #echo "類加載路徑->$CLASSPATH" #echo "參數數量$#" #echo "參數->""$@" java -cp "$CLASSPATH" "$@" } i=0 while (($i<$#)); do let j=i+1 arg=$(eval echo "$""$j") #echo $arg if [ "$arg" == "-cp" ]; then shift 1 addClassPath=$(eval echo "$""$j") CLASSPATH="$CLASSPATH:${addClassPath// /:}" # 添加類路徑, 同時替換空格爲':', 方便使用通配符'*'和'?' else # 這裏開始是類名 javaClass="$(eval echo "$""$j")" #echo "執行類$javaClass" let k=j+1 toJava="" while (($k<=$#)); do toJava="$toJava '$(eval echo "$""$k")'" #echo "$toJava" let k++ done eval startJava '"$javaClass"' $toJava exit 0 fi let i++ done
該腳本最新版本請在 Github下載apache
jk 腳本使用範例:ubuntu
sudo jk -cp 'nginx.jar:tomcat-embed-core-9.0.24.jar' -cp 'spring/libs/sp*SE.jar' -cp tomcat-annotations-api-9.0.24.jar develon.java.EmbeddedTomcatKt 請輸入主目錄 工做目錄: /home/ubuntu/www/. 啓用 Spring Sep 29, 2019 5:05:40 PM org.apache.coyote.AbstractProtocol init INFO: Initializing ProtocolHandler ["http-nio-80"] Sep 29, 2019 5:05:40 PM org.apache.catalina.core.StandardService startInternal INFO: Starting service [Tomcat] Sep 29, 2019 5:05:40 PM org.apache.catalina.core.StandardEngine startInternal INFO: Starting Servlet engine: [Apache Tomcat/9.0.24] 開始注射 DispatcherServlet -> STARTING_PREP 注射完成 Sep 29, 2019 5:05:41 PM org.apache.catalina.core.ApplicationContext log INFO: Initializing Spring DispatcherServlet 'dispatcher' Sep 29, 2019 5:05:41 PM org.springframework.web.servlet.FrameworkServlet initServletBean INFO: Initializing Servlet 'dispatcher' Sep 29, 2019 5:05:42 PM org.springframework.web.servlet.FrameworkServlet initServletBean INFO: Completed initialization in 1365 ms Sep 29, 2019 5:05:42 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["http-nio-80"] 嵌入式tomcat啓動完畢!