在服务器上部署嵌入式 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启动完毕!