• Kotlin 丢失了一些 JRE 类


    在服务器上部署嵌入式 Tocmat 时, 发现了 java.lang.NoClassDefFoundError 异常 org.ietf.jgss.GSSException:

    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 似乎是完全有自己的一副运行时类库, 所以还是存在一定程度的不兼容

    /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 的基本类库都是哪些呢?

    kotlin-stdlib.jar
    kotlin-reflect.jar
    kotlin-script-runtime.jar
    

    在我的 Ubuntu 上

    /snap/kotlin/38/lib/kotlin-stdlib.jar
    /snap/kotlin/38/lib/kotlin-reflect.jar
    

    这些就足以令我的 Tomcat 跑起来了

    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, 那我们必须写一个脚本

    #!/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下载

    jk 脚本使用范例:

    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启动完毕!
    
  • 相关阅读:
    linux里终端安转视频播放器的操作及显示
    String字符串操作
    普通类 抽象类 接口
    java基础
    关于window的端口查看及tomcat的端口修改问题
    eclipse的应用和整理
    mysql学习
    echarts的使用
    Failed to read candidate component class
    oracle学习笔记2
  • 原文地址:https://www.cnblogs.com/develon/p/11609668.html
Copyright © 2020-2023  润新知