NoClassDefFoundError: com/google/api/client/auth/oauth2/Credential

NoClassDefFoundError: com/google/api/client/auth/oauth2/Credential

添加 suggested 行:

CountDownLatch latch = new CountDownLatch(1);
..
latch.countDown();
latch.await();

在来自 Netbeans 的 ant jar 之后,围绕数据库查询公开了以下异常:

-do-jar:

jar:

BUILD SUCCESSFUL
Total time: 2 seconds
thufir@doge:~/NetBeansProjects/Firebase$ 
thufir@doge:~/NetBeansProjects/Firebase$ java -jar dist/
Firebase.jar  lib/          
thufir@doge:~/NetBeansProjects/Firebase$ java -jar dist/Firebase.jar 
Exception in thread "pool-4-thread-1" java.lang.NoClassDefFoundError: com/google/api/client/auth/oauth2/Credential
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
    at java.net.URLClassLoader.access0(URLClassLoader.java:73)
    at java.net.URLClassLoader.run(URLClassLoader.java:368)
    at java.net.URLClassLoader.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at com.google.firebase.auth.FirebaseCredentials$CertCredential.fetchCredential(FirebaseCredentials.java:276)
    at com.google.firebase.auth.FirebaseCredentials$BaseCredential.call(FirebaseCredentials.java:229)
    at com.google.firebase.auth.FirebaseCredentials$BaseCredential.call(FirebaseCredentials.java:224)
    at com.google.firebase.tasks.Tasks.run(Tasks.java:78)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: com.google.api.client.auth.oauth2.Credential
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 19 more
^Cthufir@doge:~/NetBeansProjects/Firebase$ 
thufir@doge:~/NetBeansProjects/Firebase$    
thufir@doge:~/NetBeansProjects/Firebase$ ll dist/lib/
total 5024
drwxrwxr-x 2 thufir thufir    4096 Jul  3 20:19 ./
drwxrwxr-x 3 thufir thufir    4096 Jul  3 20:18 ../
-rw-rw-r-- 1 thufir thufir  648491 Jul  3 20:19 firebase-admin-5.2.0.jar
-rw-rw-r-- 1 thufir thufir  430683 Jul  3 20:19 firebase-client-jvm-2.2.3.jar
-rw-rw-r-- 1 thufir thufir  610019 Jul  3 20:19 firebase-server-sdk-3.0.3.jar
-rw-rw-r-- 1 thufir thufir  199100 Jul  3 20:19 google-api-client-1.22.0.jar
-rw-rw-r-- 1 thufir thufir  239194 Jul  3 20:19 google-api-client-1.4.1-beta.jar
-rw-rw-r-- 1 thufir thufir   16799 Jul  3 20:19 google-api-client-auth-oauth2-1.2.3-alpha.jar
-rw-rw-r-- 1 thufir thufir    6720 Jul  3 20:19 google-http-client-jackson2-1.22.0.jar
-rw-rw-r-- 1 thufir thufir 2575022 Jul  3 20:19 guava-22.0.jar
-rw-rw-r-- 1 thufir thufir  316575 Jul  3 20:19 jackson-core-2.9.0.pr4.jar
-rw-rw-r-- 1 thufir thufir   15896 Jul  3 20:19 jackson-jaxrs-json-provider-2.9.0.pr4.jar
-rw-rw-r-- 1 thufir thufir   57264 Jul  3 20:19 json-20170516.jar
thufir@doge:~/NetBeansProjects/Firebase$ 

代码:

package dur.bounceme.net.firebase;

import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.auth.FirebaseCredentials;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.logging.Level;
import java.util.logging.Logger;

public class FirebaseQuery {

    private static final Logger log = Logger.getLogger(FirebaseQuery.class.getName());
    private DatabaseReference databaseReference = null;
    private Properties firebaseProperties = null;

    public FirebaseQuery() {
    }

    void setProperties(Properties firebaseProperties) {
        this.firebaseProperties = firebaseProperties;
    }

    void pushUsers(List<User> users) {
        for (User u : users) {
            databaseReference.child("users").child(u.uuid.toString()).setValue(u);
        }
    }

    void tryQuery() {
        try {
            query();
        } catch (IOException ex) {
            Logger.getLogger(FirebaseQuery.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InterruptedException ex) {
            Logger.getLogger(FirebaseQuery.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void query() throws FileNotFoundException, IOException, InterruptedException {
        String url = firebaseProperties.getProperty("url");
        FileInputStream serviceAccount = new FileInputStream("serviceAccountKey.json");
        FirebaseOptions options = new FirebaseOptions.Builder()
                .setCredential(FirebaseCredentials.fromCertificate(serviceAccount))
                .setDatabaseUrl(url)
                .build();
        FirebaseApp firebaseApp = FirebaseApp.initializeApp(options);
        FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance(firebaseApp, url);
        databaseReference = firebaseDatabase.getReference().getRoot();

        CountDownLatch latch = new CountDownLatch(1);
        databaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                String key = null;
                String value = null;
                for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
                    key = childSnapshot.getKey();
                    value = (String) childSnapshot.getValue();
                    log.info(key + "\t\t" + value);
                }
                latch.countDown();
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                latch.countDown();
                throw databaseError.toException();
            }
        });
        latch.await();
    }
}

据我所知,这些是 correct 包,但显然不是,因为没有 Credential class:

thufir@doge:~/NetBeansProjects/Firebase$ 
thufir@doge:~/NetBeansProjects/Firebase$ jar -tf dist/lib/google-api-client-auth-oauth2-1.2.3-alpha.jar 
META-INF/
META-INF/MANIFEST.MF
com/
com/google/
com/google/api/
com/google/api/client/
com/google/api/client/auth/
com/google/api/client/auth/oauth2/
com/google/api/client/auth/oauth2/AccessProtectedResource$AccessTokenIntercepter.class
com/google/api/client/auth/oauth2/AccessProtectedResource$UsingAuthorizationHeader.class
com/google/api/client/auth/oauth2/AccessProtectedResource$UsingQueryParameter.class
com/google/api/client/auth/oauth2/AccessProtectedResource$UsingFormEncodedBody.class
com/google/api/client/auth/oauth2/AccessProtectedResource.class
com/google/api/client/auth/oauth2/AccessTokenRequest$AuthorizationCodeGrant.class
com/google/api/client/auth/oauth2/AccessTokenRequest$ResourceOwnerPasswordCredentialsGrant.class
com/google/api/client/auth/oauth2/AccessTokenRequest$AssertionGrant.class
com/google/api/client/auth/oauth2/AccessTokenRequest$RefreshTokenGrant.class
com/google/api/client/auth/oauth2/AccessTokenRequest.class
com/google/api/client/auth/oauth2/AccessTokenErrorResponse$KnownError.class
com/google/api/client/auth/oauth2/AccessTokenErrorResponse.class
com/google/api/client/auth/oauth2/AccessTokenResponse.class
com/google/api/client/auth/oauth2/AuthorizationRequestUrl$ResponseType.class
com/google/api/client/auth/oauth2/AuthorizationRequestUrl.class
com/google/api/client/auth/oauth2/AuthorizationResponse$KnownError.class
com/google/api/client/auth/oauth2/AuthorizationResponse.class
META-INF/maven/
META-INF/maven/com.google.api.client/
META-INF/maven/com.google.api.client/google-api-client-auth-oauth2/
META-INF/maven/com.google.api.client/google-api-client-auth-oauth2/pom.xml
META-INF/maven/com.google.api.client/google-api-client-auth-oauth2/pom.properties
thufir@doge:~/NetBeansProjects/Firebase$ 

我在哪里可以下载这个特定 class 的 JAR?无论是 运行 从 CLI 通过 ant run,运行 如上所述直接使用 JAR,还是使用 Netbeans,都会发生异常。

Class 在 verson 1.7 中添加见 java docs

升级你的罐子。参见 download