Need help compiling sponge plugin with forgegradle

Hi All!

I have been asked to update a sponge plugin that is trying to interact with a forge mod. The mod’s only purpose is to access NBT functions, but I get this error
java.lang.NoSuchMethodError: net.minecraft.nbt.NBTTagCompound.getInteger(Ljava/lang/String;)I

I’ve been talking to people on the #spongedev IRC, and from what I understand, the error comes because I am not re-obfuscating the method. This is completely understandable since I’m not building from forgegradle.

It was suggested that I build using forgegradle:

IRC Conversation

phroa> forgegradle helps
SparkVGX> forgegradle for use with compiling the plugin?
SparkVGX> Is there an orthodox way to let my sponge plugin access forge/minecraft code?
<A​s​h​e​r​s​l​a​b​> why not make a forge mod instead?
SparkVGX> The owner of a server has asked me to update a sponge plugin and wants it to stay as a sponge plugin unfortunately
<A​s​h​e​r​s​l​a​b​> ahhh
<A​s​h​e​r​s​l​a​b​> well have fun with that xD
<A​s​h​e​r​s​l​a​b​> just btw it CAN be just a server-side mod…
<A​s​h​e​r​s​l​a​b​> just sponge wouldn’t load it, forge would.
SparkVGX> but I’ve yet to discern how they’ve managed to compile their sponge plugin with reobf the forge src code lol
<A​s​h​e​r​s​l​a​b​> ¯_(ツ)_/¯
Deamon> you make it as you would a forge mod using forge gradle (or vanilla gradle)

However, when I asked how to do so, everyone disappeared. In my own efforts, I was unable to build just by putting my src folder in and adding the sponge dependencies.

SpongeForge Build: 1.10.2-2281-5.2.0-BETA-2597
Java Version: 1.8

ForgeError

https://gist.github.com/SparkVGX/e20142fc1a6a19d82db73729d506c8ce

My normal sponge build gradle file which I’ve used to correctly build other normal sponge plugins that don’t require weird interactions with forge:

Sponge Build.gradle file
plugins {
    id "com.qixalite.spongestart" version "1.6.0"
    id 'java'
    id 'com.github.johnrengelman.shadow' version '1.2.3'
    //id 'org.spongepowered.plugin' version '0.8.1'
}

defaultTasks 'build', 'shadowJar'

group = 'net.sparkvgx.daycare' // TODO
version = '1.0-SNAPSHOT'
description = 'A daycare plugin'
sourceCompatibility = 1.8

repositories {
    mavenCentral()
    maven {
        name 'Sonatype'
        url 'https://oss.sonatype.org/content/repositories/snapshots/'
    }
    maven { url "https://jitpack.io" }
    maven {
        name 'sponge'
        url 'http://repo.spongepowered.org/maven'
    }
    maven { url "http://repo.maven.apache.org/maven2" }
    //maven { url  "http://dl.bintray.com/austinv11/maven" }
}

spongestart{
    eula true

    //optional configs
    //spongeForgeBuild '2575'
    //forgeServerFolder 'run'

    //optional settings, takes latest version by default
    minecraft '1.10.2'
    type 'bleeding'
    spongeForgeVersion '1.10.2-2281-5.2.0-BETA-2597'
    spongeVanillaVersion '1.10.2-5.2.0-BETA-393'
}

dependencies {
    compile group: 'com.zaxxer', name: 'HikariCP', version:'2.4.3'
    compileOnly 'org.spongepowered:spongeapi:5.2.0-SNAPSHOT'
    compileOnly 'org.spongepowered:spongecommon:5.2.0-SNAPSHOT:dev'
    compileOnly fileTree(dir: 'libs', include: '*.jar')
}

My weird attempt at a forge build.gradle file that I’m trying to make build my sponge plugin, so that I can have access to forge methods:

forge build.gradle file
buildscript {
    repositories {
        jcenter()
        maven { url = "http://files.minecraftforge.net/maven" }
    }
    dependencies {
        classpath 'net.minecraftforge.gradle:ForgeGradle:2.2-SNAPSHOT'
    }
}
apply plugin: 'net.minecraftforge.gradle.forge'
//Only edit below this line, the above code adds and enables the nessasary things for Forge to be setup.


version = "1.1"
group= "net.sparkvgx.daycare" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "daycare"

sourceCompatibility = targetCompatibility = "1.8" // Need this here so eclipse task generates correctly.
compileJava {
    sourceCompatibility = targetCompatibility = "1.8"
}

repositories {
    mavenCentral()
    maven {
        name 'Sonatype'
        url 'https://oss.sonatype.org/content/repositories/snapshots/'
    }
    maven { url "https://jitpack.io" }
    maven {
        name 'sponge'
        url 'http://repo.spongepowered.org/maven'
    }
    maven { url "http://repo.maven.apache.org/maven2" }
    //maven { url  "http://dl.bintray.com/austinv11/maven" }
}

minecraft {
    version = "1.10.2-12.18.3.2281"
    runDir = "run"
    
    // the mappings can be changed at any time, and must be in the following format.
    // snapshot_YYYYMMDD   snapshot are built nightly.
    // stable_#            stables are built at the discretion of the MCP team.
    // Use non-default mappings at your own risk. they may not allways work.
    // simply re-run your setup task after changing the mappings to update your workspace.
    mappings = "snapshot_20161111"
    // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
}

dependencies {
    // you may put jars on which you depend on in ./libs
    // or you may define them like so..
    //compile "some.group:artifact:version:classifier"
    //compile "some.group:artifact:version"
      
    // real examples
    //compile 'com.mod-buildcraft:buildcraft:6.0.8:dev'  // adds buildcraft to the dev env
    //compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env

    // the 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime.
    //provided 'com.mod-buildcraft:buildcraft:6.0.8:dev'

    // the deobf configurations:  'deobfCompile' and 'deobfProvided' are the same as the normal compile and provided,
    // except that these dependencies get remapped to your current MCP mappings
    //deobfCompile 'com.mod-buildcraft:buildcraft:6.0.8:dev'
    //deobfProvided 'com.mod-buildcraft:buildcraft:6.0.8:dev'

    // for more info...
    // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
    // http://www.gradle.org/docs/current/userguide/dependency_management.html

    compile group: 'com.zaxxer', name: 'HikariCP', version:'2.4.3'
    compileOnly 'org.spongepowered:spongeapi:5.2.0-SNAPSHOT'
    compileOnly 'org.spongepowered:spongecommon:5.2.0-SNAPSHOT:dev'
    compileOnly fileTree(dir: 'libs', include: '*.jar')
}

processResources
{
    // this will ensure that this task is redone when the versions change.
    inputs.property "version", project.version
    inputs.property "mcversion", project.minecraft.version

    // replace stuff in mcmod.info, nothing else
    from(sourceSets.main.resources.srcDirs) {
        include 'mcmod.info'
                
        // replace version and mcversion
        expand 'version':project.version, 'mcversion':project.minecraft.version
    }
        
    // copy everything else, thats not the mcmod.info
    from(sourceSets.main.resources.srcDirs) {
        exclude 'mcmod.info'
    }
}

This is the stack trace error I get when trying to build it with the above forge grade. It complains of a duplicate mcmod info file, but I have no idea why.

Stacktrace error
* What went wrong:
Execution failed for task ':reobfJar'.
> java.util.zip.ZipException: duplicate entry: mcmod.info

* Try:
Run with --info or --debug option to get more log output.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':reobfJar'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
        at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
        at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:66)
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:52)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
        at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:203)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:185)
        at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:66)
        at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:50)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:25)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:110)
        at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
        at org.gradle.execution.DefaultBuildExecuter.access$000(DefaultBuildExecuter.java:23)
        at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:43)
        at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30)
        at org.gradle.initialization.DefaultGradleLauncher$4.run(DefaultGradleLauncher.java:153)
        at org.gradle.internal.Factories$1.create(Factories.java:22)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:53)
        at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:150)
        at org.gradle.initialization.DefaultGradleLauncher.access$200(DefaultGradleLauncher.java:32)
        at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:98)
        at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:92)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:63)
        at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:92)
        at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:83)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:99)
        at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
        at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:48)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:30)
        at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:81)
        at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:46)
        at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:52)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
        at org.gradle.util.Swapper.swap(Swapper.java:38)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.health.DaemonHealthTracker.execute(DaemonHealthTracker.java:40)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.health.HintGCAfterBuild.execute(HintGCAfterBuild.java:41)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)        at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:237)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
        at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
Caused by: org.gradle.api.UncheckedIOException: java.util.zip.ZipException: duplicate entry: mcmod.info
        at org.gradle.internal.UncheckedException.throwAsUncheckedException(UncheckedException.java:43)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:78)
        at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:228)
        at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:221)
        at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:210)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:621)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:604)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
        ... 68 more
Caused by: java.util.zip.ZipException: duplicate entry: mcmod.info
        at net.minecraftforge.gradle.user.TaskSingleReobf.applyExtraTransformers(TaskSingleReobf.java:253)
        at net.minecraftforge.gradle.user.TaskSingleReobf.doTask(TaskSingleReobf.java:184)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:75)
        ... 75 more


BUILD FAILED

Here is the function I’m trying to access from the sponge plugin. The nbt handler mod itself is compiled correctly with gradlew in a proper forgegradle project, so I know it’s to do with how I’m compiling my plugin.

getInteger function
public static int getInteger(Object object, String string) {
    NBTTagCompound nbt = (NBTTagCompound)object;
    return nbt.getInteger(string);
}

Any assistance would be greatly appreciated. If I haven’t provided enough information, please let me know.

In the end, I just want to be able to access the minecraft classes like ItemStack and NBTTagCompound so if there’s a better way to do this, I am open to suggestions. I’m not adamant about keeping to this plugin-forge integration if there’s an easier option. I’m just limited by the fact that it specifically requires access to another forge mod, which I then assume also requires forge in order to help compile it.

It seems that sponge includes an APT to generate the mcmod.info, so they collide. Try deleting the mcmod.info from src/main/resources, and for good measure aso comment out the lines

    // replace stuff in mcmod.info, nothing else
    from(sourceSets.main.resources.srcDirs) {
        include 'mcmod.info'
                
        // replace version and mcversion
        expand 'version':project.version, 'mcversion':project.minecraft.version
    }
1 Like

Hiya!

After some more googling, I found this topic on the forums. By setting up a new project with their intellij plugin and selecting both sponge and forge, it set up a build file I was then able to use to build my plugin properly :slight_smile: Minecraft Dev for IntelliJ - #29 by SparkVGX

Now I just need to figure out how to make it start a spongeforge server in the environment, but I’ll ask about that in their own topic.
Thanks all.