Can't call public method of non-public class: public (Google gcloud library)

前端 未结 4 905
没有蜡笔的小新
没有蜡笔的小新 2021-01-06 13:46

I am attempting to use the gcloud library.

(ns firengine.state
  (:import
   [com.google.cloud AuthCredentials]
   [com.google.cloud.datastore DatastoreOpti         


        
相关标签:
4条回答
  • 2021-01-06 14:34

    As Shlomi said, that's a long running bug. Following the advice of Noam Ben Ari on the clj-jira, I've managed the circumvent the issue by writing a small java class that wraps the client creation. I can then use that directly from my clj code.

    package pubsub_echo.pubsub;
    
    import com.google.cloud.AuthCredentials;
    import com.google.cloud.pubsub.PubSub;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    
    public class GCloudPubSub {
    
        public PubSub getClient() throws FileNotFoundException, IOException {
            PubSubOptions.Builder optionsBuilder = PubSubOptions.builder();
            ClassLoader classLoader = getClass().getClassLoader();
            FileInputStream authStream = new FileInputStream(classLoader.getResource("SERVICE_ACCOUNT.json").getPath());
            AuthCredentials creds = AuthCredentials.createForJson(authStream);
    
            return optionsBuilder
                .authCredentials(creds)
                .projectId("PROJECT_ID")
                .build()
                .service();
        }
    
    }
    

    For guidance on adding Java compilation to your project:

    https://github.com/technomancy/leiningen/blob/master/doc/MIXED_PROJECTS.md

    0 讨论(0)
  • 2021-01-06 14:38

    Yeah.... that problem. You wouldnt believe it, but its actually an open bug in the jdk from ... wait for it ... 1999!

    You can read about it more in clojure jira and on google groups.

    You might have to make your own java wrapper to avoid this, or ask the library author to take this old known java bug into consideration.

    If you dont want to write your own java wrapper, and the author insists that "this is the best design, like, ever!", then you could always force it by setting the method accessibility with (.setAccessible method true) and some more custom reflection code..

    Good luck!

    0 讨论(0)
  • 2021-01-06 14:38

    Completely inspired by hironroy's answer, I worked through an isolated example of getting this working. Created the file below in src/gcloud/GcloduDatastore.java in the following github project.

    package gcloud;
    
    import com.google.cloud.AuthCredentials;
    import com.google.cloud.datastore.Datastore;
    import com.google.cloud.datastore.DatastoreOptions;
    import com.google.cloud.datastore.DatastoreOptions.Builder;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    
    public class GCloudDatastore {
    
        public static Datastore getDatastore() throws FileNotFoundException, IOException {
            DatastoreOptions.Builder optionsBuilder = DatastoreOptions.builder();
            FileInputStream authStream = new FileInputStream(System.getenv("SERVICE_ACCOUNT_DOT_JSON_PATH"));
            AuthCredentials creds = AuthCredentials.createForJson(authStream);
    
            return optionsBuilder
                .authCredentials(creds)
                .projectId(System.getenv("PROJECT_ID"))
                .build()
                .service();
        }
    
    }
    
    0 讨论(0)
  • 2021-01-06 14:42

    so, i am a complete Clojure noob and ran into a similar error using Caffeine Cache: "IllegalArgumentException Can't call public method of non-public class: public default void com.github.benmanes.caffeine.cache.LocalManualCache.put(java.lang.Object,java.lang.Object) clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:88)"

    my original function signature was this:

    (defn get
      [cache key]
      (.getIfPresent cache key)
      )
    

    and i think the issue is that Clojure could not figure out where to apply Cache's .getIfPresent function. Adding the type fixed it:

    (defn get
      [^Cache cache key]
      (.getIfPresent cache key)
      )
    

    Even though it's not a direct answer and your question went over my head, I hope this helps.

    0 讨论(0)
提交回复
热议问题