Jump to content

[SOLVED] [1.14.x] Non mod dependencies


Recommended Posts

Posted (edited)

I was used to adding my dependencies by just dropping all ".jar" files into the "mods" folder. This does not work anymore in 1.14 (NoClassDefFoundError for the first loaded class of my library).
I tried to use the way described here: Dependency extraction

 

I've created a folder "libraries" in "META-INF" and placed a jar there (e.g. "Test.jar").
I've also added a few lines to my "build.gradle" to automatically write the correct manifest.

jar {
  manifest {
    attributes(
      'ContainedDeps': 'Test.jar'
    )
  }
}

 

I did check my built mod for the contained files. It correctly contains the "libraries" folder in the META-INF with "Test.jar" and the line "ContainedDeps: Test.jar" is added to "MANIFEST.MF".
When I try to start a server with the mod, a NoClassDefFoundError is thrown, which means my library is not loaded. Please note that everything is working when I start with "gradlew runServer".

 

My dependency is also only server side. Previously I did that by adding the dependency only in the servers mod folder. How would I do that now?

Edited by kajetan
issue solved
Posted
On 8/30/2019 at 12:26 AM, Animefan8888 said:

Try the libraries folder in the root directory.

It still doesn't work. I also tried manipulating the manifest of Forge (adding my dependency under "Class-Path"). It probably would work this way, but a Signature-Exception is thrown, because the manifest signature isn't the same anymore due to my change.

Posted

I have a local folder where I keep all my libraries. I point to it in my build.gradle like this:

//...
// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
apply plugin: 'eclipse'
apply plugin: 'maven-publish'

repositories {
    flatDir {
        name = "locallib"
        dir "../~lib"
    }
}

//The rest of the file...


Later, in the dependencies section, I have this:

dependencies {
   //...
   compile "themikeste1:librarymodid:" + mcversion + "-modversion"
}

 

My mods.toml for the mod I'm working on contains this:

[[dependencies.modid]]
   modId="librarymodid"
   mandatory=true
   versionRange="[0,)"
   ordering="NONE"
   side="BOTH"

You could change the side attribute to say SERVER if you want it to only be applied on the server.

 

My jar manifest for the mod I'm depending on is set up like this:

jar {
    manifest {
        attributes([
            "Specification-Title": "modname",
            "Specification-Vendor": "TheMikeste1",
            "Specification-Version": "1", // We are version 1 of ourselves //Are we though?
            "Implementation-Title": project.name,
            "Implementation-Version": "${modVersion}",
            "Implementation-Vendor" :"TheMikeste1",
            "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
            "Maven-Artifact": "themikeste1:librarymodid:" + version
        ])
    }
}

 

I then just publish the mod I depend on to that folder and I'm able to use it as normal. I have no idea if this is how you're supposed to do it, but it works for me. ??‍♂️

Posted (edited)
18 hours ago, TheMikeste1 said:

I have a local folder where I keep all my libraries. I point to it in my build.gradle like this:


//...
// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
apply plugin: 'eclipse'
apply plugin: 'maven-publish'

repositories {
    flatDir {
        name = "locallib"
        dir "../~lib"
    }
}

//The rest of the file...


Later, in the dependencies section, I have this:


dependencies {
   //...
   compile "themikeste1:librarymodid:" + mcversion + "-modversion"
}

I'm already doing this except that my dependency line is like "compile files('./libs/Test.jar')".
 

18 hours ago, TheMikeste1 said:

My mods.toml for the mod I'm working on contains this:


[[dependencies.modid]]
   modId="librarymodid"
   mandatory=true
   versionRange="[0,)"
   ordering="NONE"
   side="BOTH"

You could change the side attribute to say SERVER if you want it to only be applied on the server.

As stated my dependency is not a mod. I just have a Jar, which has no mod id.

 

18 hours ago, TheMikeste1 said:

My jar manifest for the mod I'm depending on is set up like this:


jar {
    manifest {
        attributes([
            "Specification-Title": "modname",
            "Specification-Vendor": "TheMikeste1",
            "Specification-Version": "1", // We are version 1 of ourselves //Are we though?
            "Implementation-Title": project.name,
            "Implementation-Version": "${modVersion}",
            "Implementation-Vendor" :"TheMikeste1",
            "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
            "Maven-Artifact": "themikeste1:librarymodid:" + version
        ])
    }
}

 

I did try that the Java way with "Class-Path: lib/Test.jar". I also tried several paths without success. 
 

18 hours ago, TheMikeste1 said:

I then just publish the mod I depend on to that folder and I'm able to use it as normal. I have no idea if this is how you're supposed to do it, but it works for me. ??‍♂️

So you drop your "lib"-folder in the mod folder ? Forge cannot find my library there, because I cannot adapt the previous steps to my problem.

 


EDIT: I tried something nasty. I headed into the "libraries" folder and swapped the least used looking library with mine (which was java3d). I was able to start a server this way. So it is confirmed just a dependency problem, because I cannot configure anywhere to load my own library.

 

EDIT 2: I was able to start the server by compiling the mod with "embed" as described here. Just to clarify - shading or a simply embed is not what I want. I need the possibility to change the library without recompiling the mod.
 

Edited by kajetan
Posted

I solved the problem with a dirty hack.
 

public static void loadDependencies()
{
  URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();

  try
  {
    Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});
    method.setAccessible(true);
    method.invoke(sysloader, getURL("mods/libs/Test.jar")); 
  }
  catch(Throwable t)
  {
  	t.printStackTrace();
  }
}

private static URL getURL(String s) throws MalformedURLException
{
	return new File(s).toURI().toURL();
}

 

Now I can load arbitrary library jars as I could before. The method is called in the constructor of the mod.

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.

Announcements



×
×
  • Create New...

Important Information

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