Why Does Clojure Use the Context Classloader by Default?

前端 未结 1 1001
旧巷少年郎
旧巷少年郎 2020-12-31 02:28

Why is use-context-classloader set to true by default?

Why doesn\'t Clojure use the current class loader?

相关标签:
1条回答
  • 2020-12-31 03:04

    you can override its behavior by setting clojure.lang.Compiler.LOADER to the class loader ie.

    final ClassLoader ccl= ClojurePlugin.class.getClassLoader();
    clojure.lang.Var.pushThreadBindings(clojure.lang.RT.map( clojure.lang.Compiler.LOADER, ccl) );
    try {
      ...
      clojure.lang.RT.loadResourceScript( cljFile );
      ...
    }finally{
      clojure.lang.RT.popThreadBindings();
    }
    

    where ClojurePlugin is your class.

    but when you're using RT class the first time ever(ie. when RT class is loaded) it will use context classloader to load ie. clojure/core, so you might want to wrap the above code into:

    ClassLoader previous = Thread.currentThread().getContextClassLoader();
    final ClassLoader parentClassLoader = ClojurePlugin.class.getClassLoader();
    Thread.currentThread().setContextClassLoader(parentClassLoader);
    try {
      ...
      //above code here
      ...
    } finally {
      Thread.currentThread().setContextClassLoader(previous);
    }
    

    else you risk getting some error messages like:

    Caused by: java.io.FileNotFoundException: Could not locate clojure/core__init.class or clojure/core.clj on classpath:
            at clojure.lang.RT.load(RT.java:432)
            at clojure.lang.RT.load(RT.java:400)
            at clojure.lang.RT.doInit(RT.java:436)
            at clojure.lang.RT.<clinit>(RT.java:318)
            ... 16 more
    

    otherwise if you do this but not the former, you get something like:

    21:10:59 [SEVERE] java.io.FileNotFoundException: Could not locate Clojure resource on classpath: cljminecraft/core.clj
    21:10:59 [SEVERE]       at clojure.lang.RT.loadResourceScript(RT.java:366)
    21:10:59 [SEVERE]       at clojure.lang.RT.loadResourceScript(RT.java:346)
    21:10:59 [SEVERE]       at clojure.lang.RT.loadResourceScript(RT.java:338)
    21:10:59 [SEVERE]       at cljminecraft.ClojurePlugin.loadClojureFile(ClojurePlugin.java:25)
    21:10:59 [SEVERE]       at cljminecraft.ClojurePlugin.loadClojureNameSpace(ClojurePlugin.java:38)
    21:10:59 [SEVERE]       at cljminecraft.ClojurePlugin.start(ClojurePlugin.java:53)
    21:10:59 [SEVERE]       at cljminecraft.BasePlugin.onEnable(BasePlugin.java:235)
    21:10:59 [SEVERE]       at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:217)
    21:10:59 [SEVERE]       at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:374)
    21:10:59 [SEVERE]       at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:381)
    21:10:59 [SEVERE]       at org.bukkit.craftbukkit.CraftServer.loadPlugin(CraftServer.java:270)
    21:10:59 [SEVERE]       at org.bukkit.craftbukkit.CraftServer.enablePlugins(CraftServer.java:252)
    21:10:59 [SEVERE]       at net.minecraft.server.MinecraftServer.j(MinecraftServer.java:320)
    21:10:59 [SEVERE]       at net.minecraft.server.MinecraftServer.e(MinecraftServer.java:299)
    21:10:59 [SEVERE]       at net.minecraft.server.MinecraftServer.a(MinecraftServer.java:258)
    21:10:59 [SEVERE]       at net.minecraft.server.DedicatedServer.init(DedicatedServer.java:147)
    21:10:59 [SEVERE]       at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:398)
    21:10:59 [SEVERE]       at net.minecraft.server.ThreadServerApplication.run(SourceFile:856)
    

    if you do neither (but you still call something like clojure.lang.RT.loadResourceScript( cljFile ); then you get the first error (obviously)

    0 讨论(0)
提交回复
热议问题