Skip to content

No thread context classloader when invoking server main, breaks ServiceLoader lookups (javax.script on Purpur) #2

Description

@fzzgg

Booting Purpur 1.21.7 with tack 0.1.1-beta (source build) dies while
loading the world. Purpur gets null back from its javax.script
lookup (Rhino), so Entity.scriptEngine is null. Same jar works
fine under plain java and under Paperclip.

Env: Debian hosts, server runs in Docker on
amazoncorretto:26-al2023 (glibc, tack needs it).

tack invokes main on a JNI-attached thread without setting a
context classloader first, so ServiceLoader falls back to
bootstrap and never sees the app classpath. Setting it before
the call, the way Paperclip does, fixes it. The snippet below
is what we run in exec_jvm (src/launcher.rs), right before
the main_class lookup, on 11 prod servers since late August:

let system_loader = env
    .call_static_method(
        jni_str!("java/lang/ClassLoader"),
        jni_str!("getSystemClassLoader"),
        jni_sig!("()Ljava/lang/ClassLoader;"),
        &[],
    )?
    .l()
    .into_error()?;
let current_thread = env
    .call_static_method(
        jni_str!("java/lang/Thread"),
        jni_str!("currentThread"),
        jni_sig!("()Ljava/lang/Thread;"),
        &[],
    )?
    .l()
    .into_error()?;
env.call_method(
    &current_thread,
    jni_str!("setContextClassLoader"),
    jni_sig!("(Ljava/lang/ClassLoader;)V"),
    &[JValue::Object(&system_loader)],
)?;

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions