Jump to content

[1.8.9] Run Gradle Build using the Minecraft class loader


yoshiquest

Recommended Posts

This issue is rather... complicated, so bear with me.

 

The mod I am writing involves inter-op between Java and Clojure, and utilizes the Clojure compiler. The compiler is itself written in java, meaning that whenever Clojure code is in the compilation phase, a jvm is there. Unfortunately, Clojure has a bad habit (as far as I can tell) of compiling Java classes it references as well ahead of time. This means that I have run into a problem with net.minecraft.init.Blocks, as there is a static block there crashing compilation if it gets loaded before bootstrap is registered. This means that any class referring to Blocks (such as BiomeGenBase as one crucial example), will crash the game when Clojure tries to load it.

 

I was able to get around this for a time by using a bit of reflection to set the variable it was checking (alreadyRegistered in Bootstrap) to true, tricking it into letting my code compile. Unfortunately this failed as soon as I started to use BiomeGenBase directly, as the class is trying to call a method on the result of Blocks, causing a null pointer exception and crash. So I figured I might as well just call register in Bootstrap, in order to get everything while it's compiling. Sadly, this eventually causes a crash as follows:

 

sun.misc.Launcher$AppClassLoader cannot be cast to net.minecraft.launchwrapper.LaunchClassLoader

 

Presumably due to some classes wanting to reference Minecraft's class loader instead of the default class loader that Gradle is building with.

 

TL;DR: I wish to know if there is a way to change the class loader that Gradle builds with to the loader Minecraft wants, as with that I could presumably avoid all of these issues once and for all.

Currently working on a mod to provide support for the Clojure programming language in Minecraft, check it out here.

Link to comment
Share on other sites

This has nothing to do with compilation, compilation does not execute any of your code.

Post the full stack trace please.

 

I already said that CLOJURE executes some code during ahead of time compilation. I know this is true, as I can place a print line statement in the middle of my code (not in any functions or anything) and the result is printed when compiling the code, without running minecraft at all.

 

Still, if you really want the stacktrace though, there isn't much to see:

 

 

 

Exception in thread "main" java.lang.ExceptionInInitializerError, compiling:(core.clj:16:1)

at clojure.lang.Compiler$StaticMethodExpr.eval(Compiler.java:1705)

at clojure.lang.Compiler.compile1(Compiler.java:7474)

at clojure.lang.Compiler.compile(Compiler.java:7541)

at clojure.lang.RT.compile(RT.java:406)

at clojure.lang.RT.load(RT.java:451)

at clojure.lang.RT.load(RT.java:419)

at clojure.core$load$fn__5677.invoke(core.clj:5893)

at clojure.core$load.invokeStatic(core.clj:5892)

at clojure.core$load.doInvoke(core.clj:5876)

at clojure.lang.RestFn.invoke(RestFn.java:408)

at clojure.core$load_one.invokeStatic(core.clj:5697)

at clojure.core$load_one.invoke(core.clj:5692)

at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)

at clojure.core$load_lib.invokeStatic(core.clj:5736)

at clojure.core$load_lib.doInvoke(core.clj:5717)

at clojure.lang.RestFn.applyTo(RestFn.java:142)

at clojure.core$apply.invokeStatic(core.clj:648)

at clojure.core$load_libs.invokeStatic(core.clj:5774)

at clojure.core$load_libs.doInvoke(core.clj:5758)

at clojure.lang.RestFn.applyTo(RestFn.java:137)

at clojure.core$apply.invokeStatic(core.clj:648)

at clojure.core$require.invokeStatic(core.clj:5796)

at clojure.core$require.doInvoke(core.clj:5796)

at clojure.lang.RestFn.invoke(RestFn.java:421)

at forge_clj.blocks$loading__5569__auto____65.invoke(blocks.clj:1)

at clojure.lang.AFn.applyToHelper(AFn.java:152)

at clojure.lang.AFn.applyTo(AFn.java:144)

at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3652)

at clojure.lang.Compiler.compile1(Compiler.java:7474)

at clojure.lang.Compiler.compile1(Compiler.java:7464)

at clojure.lang.Compiler.compile(Compiler.java:7541)

at clojure.lang.RT.compile(RT.java:406)

at clojure.lang.RT.load(RT.java:451)

at clojure.lang.RT.load(RT.java:419)

at clojure.core$load$fn__5677.invoke(core.clj:5893)

at clojure.core$load.invokeStatic(core.clj:5892)

at clojure.core$load.doInvoke(core.clj:5876)

at clojure.lang.RestFn.invoke(RestFn.java:408)

at clojure.core$load_one.invokeStatic(core.clj:5697)

at clojure.core$compile$fn__5682.invoke(core.clj:5903)

at clojure.core$compile.invokeStatic(core.clj:5903)

at clojure.core$compile.invoke(core.clj:5895)

at clojuresque.tasks.compile$eval43$main_task_driver__45$fn__49.invoke(Unknown Source)

at clojuresque.tasks.compile$eval43$main_task_driver__45.invoke(Unknown Source)

at clojuresque.tasks.compile$eval43$main__58.invoke(Unknown Source)

at clojuresque.tasks.compile$eval63.invokeStatic(Unknown Source)

at clojuresque.tasks.compile$eval63.invoke(Unknown Source)

at clojure.lang.Compiler.eval(Compiler.java:6927)

at clojure.lang.Compiler.load(Compiler.java:7379)

at clojure.lang.Compiler.load(Compiler.java:7326)

at clojure.core$load_reader.invokeStatic(core.clj:3957)

at clojure.main$script_opt.invokeStatic(main.clj:335)

at clojure.main$script_opt.invoke(main.clj:330)

at clojure.main$main.invokeStatic(main.clj:421)

at clojure.main$main.doInvoke(main.clj:384)

at clojure.lang.RestFn.invoke(RestFn.java:408)

at clojure.lang.Var.invoke(Var.java:379)

at clojure.lang.AFn.applyToHelper(AFn.java:154)

at clojure.lang.Var.applyTo(Var.java:700)

at clojure.main.main(main.)ava:37

Caused by: java.lang.ExceptionInInitializerError

at net.minecraft.util.StringTranslate.parseLangFile(StringTranslate.java:51)

at net.minecraft.util.StringTranslate.inject(StringTranslate.java:41)

at net.minecraft.util.StringTranslate.<init>(StringTranslate.java:31)

at net.minecraft.util.StringTranslate.<clinit>(StringTranslate.java:23)

at net.minecraft.util.StatCollector.<clinit>(StatCollector.java:5)

at net.minecraft.item.Item.getUnlocalizedNameInefficiently(Item.java:284)

at net.minecraft.item.Item.getItemStackDisplayName(Item.java:413)

at net.minecraft.item.ItemStack.getDisplayName(ItemStack.java:590)

at net.minecraft.item.ItemStack.getChatComponent(ItemStack.java:1030)

at net.minecraft.stats.StatList.initMiningStats(StatList.java:164)

at net.minecraft.stats.StatList.init(StatList.java:105)

at net.minecraft.init.Bootstrap.register(Bootstrap.java:595)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:498)

at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:93)

at clojure.lang.Compiler$StaticMethodExpr.eval(Compiler.java:1698)

... 59 more

Caused by: java.lang.ClassCastException: sun.misc.Launcher$AppClassLoader cannot be cast to net.minecraft.launchwrapper.LaunchClassLoader

at net.minecraftforge.fml.common.ModClassLoader.<init>(ModClassLoader.java:51)

at net.minecraftforge.fml.common.Loader.<init>(Loader.java:190)

at net.minecraftforge.fml.common.Loader.instance(Loader.java:169)

at net.minecraftforge.fml.common.FMLCommonHandler.<init>(FMLCommonHandler.java:104)

at net.minecraftforge.fml.common.FMLCommonHandler.<clinit>(FMLCommonHandler.java:95)

... 77 more

 

 

Currently working on a mod to provide support for the Clojure programming language in Minecraft, check it out here.

Link to comment
Share on other sites

Nothing you can do then except rewrite the clojure compiler. This behavior is horribly broken.

 

Well, I'm simply wondering if it would be possible to write, say, a gradle plugin, that would set the class loader and register bootstrap before clojure gets touched.

 

I suppose a simpler question would be: can gradle interact with the java environment it is running on top of. Such as for example, would it be possible to run pieces of Minecraft's java code from Gradle.

Currently working on a mod to provide support for the Clojure programming language in Minecraft, check it out here.

Link to comment
Share on other sites

You would somehow have to run the game, then trigger the clojure compiler from within it... or something.

 

Hm, I think I have an idea that might work. I don't need to run the entire game per say, but just need to change the classloader the thread that Clojure runs on is using. So just run those few things from a plugin and it MIGHT just work.

 

Anyways, thanks for the help, I'll try some things out tomorrow.

Currently working on a mod to provide support for the Clojure programming language in Minecraft, check it out here.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.