无法调用非公共类的公共方法:公共(Google gcloud库) [英] Can't call public method of non-public class: public (Google gcloud library)

查看:57
本文介绍了无法调用非公共类的公共方法:公共(Google gcloud库)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 gcloud 库。

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

(-> (DatastoreOptions/builder)
      (.projectId "<project_id>")
      (.authCredentials
       (AuthCredentials/createForJson
        (clojure.java.io/input-stream service-account-path)))
      .build)

上述Clojure代码是从以下代码段(点按一下,单击在其他地方运行)。

The above clojure code is translated from the following code snippet (ellided, click on "Run elsewhere").

import com.google.cloud.AuthCredentials;
import com.google.cloud.datastore.DatastoreOptions;

DatastoreOptions options = DatastoreOptions.builder()
  .projectId(PROJECT_ID)
  .authCredentials(AuthCredentials.createForJson(
    new FileInputStream(PATH_TO_JSON_KEY))).build();

当我从Clojure REPL调用此代码时,出现以下错误。

When I call this code from the Clojure REPL, I get the following error.

Unhandled java.lang.IllegalArgumentException
   Can't call public method of non-public class: public
   com.google.cloud.ServiceOptions$Builder
   com.google.cloud.ServiceOptions$Builder.projectId(java.lang.String)

            Reflector.java:   88  clojure.lang.Reflector/invokeMatchingMethod
            Reflector.java:   28  clojure.lang.Reflector/invokeInstanceMethod
boot.user4590132375374459695.clj:  168  firengine.state/eval17529
boot.user4590132375374459695.clj:  167  firengine.state/eval17529
             Compiler.java: 6927  clojure.lang.Compiler/eval
                              ... elided ...

com.google.cloud.datastore.DatastoreOptions 代码可在此处找到

2016年6月29日更新:
根据 Schlomi 的以下建议,我认为也许我AOT可以在<$周围编译自己的包装器c $ c> DatastoreOptions 。

Updated June 29, 2016: Pursuant to Schlomi's advice below, I thought that maybe if I AOT compiled my own wrapper around DatastoreOptions that it would work.

(ns firengine.datastore
  (:import
   [com.google.cloud AuthCredentials]
   [com.google.cloud.datastore Datastore DatastoreOptions Entity Key KeyFactory])
  (:gen-class
   :state state
   :init init
   :constructors {[String String] []}))

(defn -init
  [^String project-id ^String service-account-path]
  (let [service-account (clojure.java.io/input-stream service-account-path)
        credentials (AuthCredentials/createForJson service-account)
        dsoptions (-> (DatastoreOptions/builder)
                      (.projectId project-id)
                      (.authCredentials credentials)
                      .build)]
      [[] {:project-id project-id
                 :service-account-path service-account-path
                 :datastore-options dsoptions}]))

我修改了引导开发任务,使其包括以下内容:

I modified my boot development task to include the following:

(deftask development
  "Launch Immediate Feedback Development Environment"
  []
  (comp
   (aot :namespace '#{firengine.datastore})
   (repl :port 6800)
   (reload)
   (watch)
   (cljs)
   (target :dir #{"target"})))

我试图像这样构造对象:

And I attempted to construct the object like so:

(def service-account-path (System/getenv "FIRENGINE_SERVICE_ACCOUNT_PATH"))

(def project-id (System/getenv "PROJECT_ID"))

(def datastore-options (firengine.datastore. project-id service-account-path))

不幸的是,我仍然遇到相同的错误吗?

Unfortunately, I still get the same error?

    clojure.lang.Compiler$CompilerException: java.lang.reflect.InvocationTargetException, compiling:(state.clj:15:1)
java.lang.reflect.InvocationTargetException: 
         java.lang.IllegalArgumentException: Can't call public method of non-public class: public com.google.cloud.ServiceOptions$Builder com.google.cloud.ServiceOptions$Builder.projectId(java.lang.String)

我不是很愿意编译 firengine.datastore

推荐答案

是的。您不会相信它的,但实际上它是 jdk中的打开错误 ...等待它……1999!

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

您可以在 clojure jira 谷歌

您可能必须制作自己的Java包装程序以避免这种情况,或者请库作者考虑这个已知的Java错误。

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.

如果您不想编写自己的Java包装程序,而作者坚持认为这是有史以来最好的设计!,那么您可以随时强制使用它通过使用(。setAccessible method true)和更多自定义反射代码设置方法的可访问性。

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..

祝您好运!

这篇关于无法调用非公共类的公共方法:公共(Google gcloud库)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆