0

I am writing a plugin for a spigot server and I need to access some data on Google sheets. I have copied the google quick start page nearly word for word. The only real difference is that I have put it in another class and have called main function TestGet. I also have changed the build.gradle somewhat to match my project structure. When I run the plugin I get NoClassDefFoundError for the JsonFactory. I'm pretty sure that I am not missing the dependency as I have included the dependencies in gradle.

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.sheets.v4.Sheets;
import com.google.api.services.sheets.v4.SheetsScopes;
import com.google.api.services.sheets.v4.model.ValueRange;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.List;

public class SheetsInterface {

    private static final String APPLICATION_NAME = "Google Sheets API Java Quickstart";
    private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
    private static final String TOKENS_DIRECTORY_PATH = "tokens";

    private static final List<String> SCOPES = Collections.singletonList(SheetsScopes.SPREADSHEETS_READONLY);
    private static final String CREDENTIALS_FILE_PATH = "/credentials.json";

    private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
    // Load client secrets.
    InputStream in = SheetsInterface.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
    GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));

    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
            HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
            .setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
            .setAccessType("offline")
            .build();
    LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
    return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
}

public static void TestGet() throws IOException, GeneralSecurityException
{
    final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
    final String spreadsheetId = "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms";
    final String range = "Class Data!A2:E";
    Sheets service = new Sheets.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
            .setApplicationName(APPLICATION_NAME)
            .build();
    ValueRange response = service.spreadsheets().values()
            .get(spreadsheetId, range)
            .execute();
    List<List<Object>> values = response.getValues();
    if (values == null || values.isEmpty()) {
        System.out.println("No data found.");
    } else {
        System.out.println("Name, Major");
        for (List row : values) {
            // Print columns A and E, which correspond to indices 0 and 4.
            System.out.printf("%s, %s\n", row.get(0), row.get(4));
        }
    }
}
}

Here is the error itself

java.lang.NoClassDefFoundError: com/google/api/client/json/JsonFactory
    at net.projectName.Main.onEnable(Main.java:17) ~[?:?]
    at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:254) ~[spigot-1.13.2.jar:git-Spigot-f56e2e7-b634e05]
    at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:340) [spigot-1.13.2.jar:git-Spigot-f56e2e7-b634e05]
    at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:403) [spigot-1.13.2.jar:git-Spigot-f56e2e7-b634e05]
    at org.bukkit.craftbukkit.v1_13_R2.CraftServer.enablePlugin(CraftServer.java:434) [spigot-1.13.2.jar:git-Spigot-f56e2e7-b634e05]
    at org.bukkit.craftbukkit.v1_13_R2.CraftServer.enablePlugins(CraftServer.java:348) [spigot-1.13.2.jar:git-Spigot-f56e2e7-b634e05]
    at net.minecraft.server.v1_13_R2.MinecraftServer.l(MinecraftServer.java:580) [spigot-1.13.2.jar:git-Spigot-f56e2e7-b634e05]
    at net.minecraft.server.v1_13_R2.MinecraftServer.a(MinecraftServer.java:542) [spigot-1.13.2.jar:git-Spigot-f56e2e7-b634e05]
    at net.minecraft.server.v1_13_R2.MinecraftServer.a(MinecraftServer.java:420) [spigot-1.13.2.jar:git-Spigot-f56e2e7-b634e05]
    at net.minecraft.server.v1_13_R2.DedicatedServer.init(DedicatedServer.java:294) [spigot-1.13.2.jar:git-Spigot-f56e2e7-b634e05]
    at net.minecraft.server.v1_13_R2.MinecraftServer.run(MinecraftServer.java:698) [spigot-1.13.2.jar:git-Spigot-f56e2e7-b634e05]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_191]
Caused by: java.lang.ClassNotFoundException: com.google.api.client.json.JsonFactory
    at java.net.URLClassLoader.findClass(Unknown Source) ~[?:1.8.0_191]
    at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:134) ~[spigot-1.13.2.jar:git-Spigot-f56e2e7-b634e05]
    at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:80) ~[spigot-1.13.2.jar:git-Spigot-f56e2e7-b634e05]
    at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_191]
    at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_191]
    ... 12 more

And here is the build.gradle:

apply plugin: "java"

sourceSets
{
    main.java.srcDir      "src/main/java"
    test.java.srcDir      "src/test/java"
    main.resources.srcDir "src/main/resources"
}

repositories {
     mavenCentral()
}

dependencies
{
    compile files("libs/spigot-api-1.13.2-R0.1-SNAPSHOT-shaded.jar")
    compile 'com.google.api-client:google-api-client:1.23.0'
    compile 'com.google.oauth-client:google-oauth-client-jetty:1.23.0'
    compile 'com.google.apis:google-api-services-sheets:v4-rev516-1.23.0'
}

If someone could help me understand what is going on that would be great. Also sorry for the massive code dump.

Liiht
  • 49
  • 7
  • 1
    You might find this useful https://stackoverflow.com/questions/17231722/com-google-api-client-json-jackson-jacksonfactory-missing-in-google-drive-examp – Cacho Castaña Feb 06 '19 at 17:14
  • I added compile " 'com.google.http-client:google-http-client-jackson:1.15.0-rc' " to my build.gradle and it still has the same result – Liiht Feb 06 '19 at 19:23
  • To add to my other comment, it sort of works, but now sometimes it gives a java.lang.NoClassDefFoundError: com/google/api/client/http/HttpRequestInitializer instead – Liiht Feb 06 '19 at 19:35

1 Answers1

0

For those interested I worked out the answer. The problem basically was that the jars the I was compiling against were around at compile time, but not when I was running them. I added this to the build.gradle file:

task fatJar(type: Jar) {
    manifest {
        attributes 'Implementation-Title': 'ProjectName',  
            'Implementation-Version': "1.0"
    }
    baseName = project.name + '-all'
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar
}

Then instead of calling "gradle build" you can call "gradle fatJar" when you want to create a Jar. This will include the jars in the jar file (slight simplification) so that the jar can find them when it is run. I found out how to do this here.

Liiht
  • 49
  • 7