Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Including transitive dependency tree doesn't work without including each dependency #175

Open
dannypas00 opened this issue May 17, 2024 · 1 comment
Labels
bug Something isn't working enhancement New feature or request

Comments

@dannypas00
Copy link

I'm attempting to include the google drive api client library, when doing so the code compiles just fine, but it crashes in runtime on a transtive dependency. I've tried using jarjar, but I've been told in discord that I'd need to include each dependency individually for this to work.

I'd like some way to "automatically" add all transitive dependencies, because the client library relies on way too many dependencies to manually manage.

build.gradle:

plugins {
    id 'java-library'
    id 'eclipse'
    id 'idea'
    id 'maven-publish'
    id 'net.neoforged.gradle.userdev' version '7.0.124'
}

version = mod_version
group = mod_group_id

repositories {
    mavenLocal()
    mavenCentral()
    google()
}

base {
    archivesName = mod_id
}

jarJar.enable()

// Mojang ships Java 21 to end users starting in 1.20.5, so mods should target Java 21.
java.toolchain.languageVersion = JavaLanguageVersion.of(21)

//minecraft.accessTransformers.file rootProject.file('src/main/resources/META-INF/accesstransformer.cfg')
//minecraft.accessTransformers.entry public net.minecraft.client.Minecraft textureManager # textureManager

// Default run configurations.
// These can be tweaked, removed, or duplicated as needed.
runs {
    // applies to all the run configs below
    configureEach {
        // Recommended logging data for a userdev environment
        // The markers can be added/remove as needed separated by commas.
        // "SCAN": For mods scan.
        // "REGISTRIES": For firing of registry events.
        // "REGISTRYDUMP": For getting the contents of all registries.
        systemProperty 'forge.logging.markers', 'REGISTRIES'

        // Recommended logging level for the console
        // You can set various levels here.
        // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
        systemProperty 'forge.logging.console.level', 'debug'

        modSource project.sourceSets.main
    }

    client {
        // Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
        systemProperty 'forge.enabledGameTestNamespaces', project.mod_id
    }

    server {
        systemProperty 'forge.enabledGameTestNamespaces', project.mod_id
        programArgument '--nogui'
    }

    // This run config launches GameTestServer and runs all registered gametests, then exits.
    // By default, the server will crash when no gametests are provided.
    // The gametest system is also enabled by default for other run configs under the /test command.
    gameTestServer {
        systemProperty 'forge.enabledGameTestNamespaces', project.mod_id
    }

    data {
        // example of overriding the workingDirectory set in configureEach above, uncomment if you want to use it
        // workingDirectory project.file('run-data')

        // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
        programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath()
    }
}

// Include resources generated by data generators.
sourceSets.main.resources { srcDir 'src/generated/resources' }

// Sets up a dependency configuration called 'localRuntime'.
// This configuration should be used instead of 'runtimeOnly' to declare
// a dependency that will be present for runtime testing but that is
// "optional", meaning it will not be pulled by dependents of this mod.
configurations {
    runtimeClasspath.extendsFrom localRuntime
}

dependencies {
    implementation "net.neoforged:neoforge:${neo_version}"

    // Google drive API
    implementation 'com.google.api-client:google-api-client:+'
    implementation 'com.google.oauth-client:google-oauth-client-jetty:+'
    implementation 'com.google.apis:google-api-services-drive:+'
    jarJar 'com.google.api-client:google-api-client:+'
    jarJar 'com.google.oauth-client:google-oauth-client-jetty:+'
    jarJar 'com.google.apis:google-api-services-drive:+'
}

tasks.named('jarJar') {
    archiveClassifier = ''
}

tasks.named('jar') {
    archiveClassifier = 'slim'
}

// This block of code expands all declared replace properties in the specified resource targets.
// A missing property will result in an error. Properties are expanded using ${} Groovy notation.
// When "copyIdeResources" is enabled, this will also run before the game launches in IDE environments.
// See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html
tasks.withType(ProcessResources).configureEach {
    var replaceProperties = [
            minecraft_version      : minecraft_version,
            minecraft_version_range: minecraft_version_range,
            neo_version            : neo_version,
            neo_version_range      : neo_version_range,
            loader_version_range   : loader_version_range,
            mod_id                 : mod_id,
            mod_name               : mod_name,
            mod_license            : mod_license,
            mod_version            : mod_version,
            mod_authors            : mod_authors,
            mod_description        : mod_description
    ]
    inputs.properties replaceProperties

    filesMatching(['META-INF/neoforge.mods.toml']) {
        expand replaceProperties
    }
}

// Example configuration to allow publishing using the maven-publish plugin
publishing {
    publications {
        register('mavenJava', MavenPublication) {
            from components.java
        }
    }
    repositories {
        maven {
            url "file://${project.projectDir}/repo"
        }
    }
}

tasks.withType(JavaCompile).configureEach {
    options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation
}

// IDEA no longer automatically downloads sources/javadoc jars for dependencies, so we need to explicitly enable the behavior.
idea {
    module {
        downloadSources = true
        downloadJavadoc = true
    }
}

error message:

java.lang.NoClassDefFoundError: com/google/api/client/json/JsonFactory
@sciwhiz12 sciwhiz12 added the bug Something isn't working label May 17, 2024
@marchermans marchermans added the enhancement New feature or request label May 19, 2024
@lukebemish
Copy link
Contributor

This is already fully possible. You can include the dependency and all its transitive deps simply by making the jarJar configuration -- or whatever other configuration you choose to use for jarJar -- transitive. Note that you will have to manually filter out any deps that MC already comes with, and that as this is a non-mod dependency you will have to add it to the runs via the convention or the runs DSL -- and that bit may not support transitive deps as easily though it should still be possible with a file collection buffer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants