Ethereum, java and clojure. Can't make it work

Hello every one,

I’ve been trying to automate some simple tasks that involve using the ethereum blockchain. I’ve been using web3j which is a java library and I’m following this tutorial on how to use it. It’s a java tutorial so I had to “translate” the code to clojure.

Everything seems to work fine except one thing and I have no idea on how to fix it.

Let’s say I have this:

(import [org.web3j.protocol Web3j]
        [org.web3j.protocol.http HttpService]
        [org.web3j.protocol.core.methods.response EthBlockNumber])

(def http (new HttpService url))
(def web3j (new Web3j/build http))

;;This is just a simple example
(-> web3j 
    (.ethBlockNumber)
    (.send))

It seems like it is working but I always get this error:
Execution error (IOException) at okio.RealBufferedSource$inputStream$1/read (RealBufferedSource.kt:154). *
Which I means I can’t see the response even if it was succesful.

On the very same tutorial you can read this:

Note: Serilization of the JSON-RPC request can raise an IOException exception, so you need to handle it.

And on the documentation page:

It has five runtime dependencies:

  • RxJava for its reactive-functional API
  • OKHttp for HTTP connections
  • Jackson Core for fast JSON serialisation/deserialization
  • Bouncy Castle for crypto
  • Jnr-unixsocket for *nix IPC (not available on Android)
    It also uses JavaPoet for generating smart contract wrappers

I’ve also looked at the source code but honestly I’m completly lost on what the issue is. All I want to do is make some transactions from my wallet to another (I have my private and public keys) so if anyone can recommend another method to acomplish this that would be helpful as well.

Thanks.


  • The whole thing
 RealBufferedSource.kt:  154  okio.RealBufferedSource$inputStream$1/read

ByteSourceJsonBootstrapper.java: 524 com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper/ensureLoaded
ByteSourceJsonBootstrapper.java: 129 com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper/detectEncoding
ByteSourceJsonBootstrapper.java: 247 com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper/constructParser
JsonFactory.java: 1485 com.fasterxml.jackson.core.JsonFactory/_createParser
JsonFactory.java: 972 com.fasterxml.jackson.core.JsonFactory/createParser
ObjectMapper.java: 3471 com.fasterxml.jackson.databind.ObjectMapper/readValue
Service.java: 50 org.web3j.protocol.Service/send
Request.java: 87 org.web3j.protocol.core.Request/send
NativeMethodAccessorImpl.java: -2 jdk.internal.reflect.NativeMethodAccessorImpl/invoke0
NativeMethodAccessorImpl.java: 62 jdk.internal.reflect.NativeMethodAccessorImpl/invoke
DelegatingMethodAccessorImpl.java: 43 jdk.internal.reflect.DelegatingMethodAccessorImpl/invoke
Method.java: 564 java.lang.reflect.Method/invoke
Reflector.java: 167 clojure.lang.Reflector/invokeMatchingMethod
Reflector.java: 438 clojure.lang.Reflector/invokeNoArgInstanceMember
REPL: 149 user/eval32836
REPL: 149 user/eval32836
Compiler.java: 7177 clojure.lang.Compiler/eval
Compiler.java: 7132 clojure.lang.Compiler/eval
core.clj: 3214 clojure.core/eval
core.clj: 3210 clojure.core/eval
interruptible_eval.clj: 82 nrepl.middleware.interruptible-eval/evaluate/fn/fn
AFn.java: 152 clojure.lang.AFn/applyToHelper
AFn.java: 144 clojure.lang.AFn/applyTo
core.clj: 665 clojure.core/apply
core.clj: 1973 clojure.core/with-bindings*
core.clj: 1973 clojure.core/with-bindings*
RestFn.java: 425 clojure.lang.RestFn/invoke
interruptible_eval.clj: 82 nrepl.middleware.interruptible-eval/evaluate/fn
main.clj: 437 clojure.main/repl/read-eval-print/fn
main.clj: 437 clojure.main/repl/read-eval-print
main.clj: 458 clojure.main/repl/fn
main.clj: 458 clojure.main/repl
main.clj: 368 clojure.main/repl
RestFn.java: 1523 clojure.lang.RestFn/invoke
interruptible_eval.clj: 79 nrepl.middleware.interruptible-eval/evaluate
interruptible_eval.clj: 56 nrepl.middleware.interruptible-eval/evaluate
interruptible_eval.clj: 145 nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
AFn.java: 22 clojure.lang.AFn/run
session.clj: 202 nrepl.middleware.session/session-exec/main-loop/fn
session.clj: 201 nrepl.middleware.session/session-exec/main-loop
AFn.java: 22 clojure.lang.AFn/run
Thread.java: 832 java.lang.Thread/run

If you know there’s a possible exception, you can catch it wit try/catch/finally and determine how to handle it therein. Here’s a lame version:

(try (-> web3j 
        (.ethBlockNumber)
        (.send))
   (catch Exception e (println (str "Error on send: " (.getMessage e))))

It’s unclear what the appropriate behavior would be if there’s an exception (I’m not familiar with the library).

1 Like

The stack trace shows something going wrong within “send”. I suppose you would run into the same problem if you translated your Clojure back to Java and ran it. To distinguish malfunctions stemming from your source code, from malfunctions stemming from libraries on the classpath, you can get the effective classpath from your Clojure tool (Leiningen or whatever) and use the same classpath with your minimal Java program.

Serilization of the JSON-RPC request can raise an IOException … Which I means I can’t see the response even if it was succesful.

The note appears to say that the library may throw an exception while composing the HTTP request. In that case, there would not be a successful response anyway. But your concern seems well-placed: in general, with any client-server arrangement, the client might successfully dispatch a request and then suffer some kind of failure before fully processing the response.

1 Like

Ok so I finally made it work by using an older version of web3j so I’m gonna go with that for now. Thanks for your suggestions!