JVM access via Go

420 views
Skip to first unread message

James Nurmi

unread,
Nov 19, 2011, 12:17:37 AM11/19/11
to golang-nuts
After failing to Google for a way to use a vendor Java class from Go,
I started writing some bindings betwixt JNI and Go, and now have
something that works, at least for my limited
test cases.

Before I bother to get it to a releasable point for others (or
admitting ownership of the code <g>), I wanted to find out a couple of
things:

- Does something like this already exist (instantiate JVM classes via
a system-local JVM, call methods on those objects, and get return
values -- from a go program) that's further along?
- Is there any outside interest?

Semantic limitations that I'd love suggestions on (in or out of the
JVM context):

- It does not seem possible in go, to dynamically define a struct,
or to attach a method to a struct, making a "magic"
'(&Object).AReflectedName(...)' impossible?
* A possible work around is something like
'(&Object).Functions["AReflectedName"](...)', but I can't think of a
way to 'sugar-over' that from the Go side.
* It is entirely probable that this could be accomplished by
substantial reflection on the Java side, but I'd like to avoid having
to ship too many Java 'stubs'.

- The JVM seems to be very concerned that thread calls are sourced
from the same context - my implementation does basic refcounting for
java, but not thread-checking.
I know syscall.Fork() does some magic w/r/t FD's, but I'm not sure
there's a way to 'hook' that in order to appropriately handle TLS for
java.

- I vaguely remember seeing something that a GOC user could do to
hook the collection of an object, but can no longer find any reference
to it,
does such functionality exist any longer?

Thanks for any thoughts,

James


P.S. It occurs to me that someone will likely ask if this would allow
some other JVM-compiled language to work, and the answer is 'probably,
depending on how closely
it follows certain semantics of Java that are not entirely specific to
the JVM', and if you're interested in talking shop/finding out, I'm
happy to share my code & notes, but I am not,
nor will ever claim to be, a Java/JVM expert =).

Evan Shaw

unread,
Nov 19, 2011, 2:14:30 AM11/19/11
to James Nurmi, golang-nuts
I don't have a use for this (yet), but I'm definitely curious to see
what it looks like.

- Evan

Brian Ketelsen

unread,
Nov 19, 2011, 1:44:38 PM11/19/11
to Evan Shaw, James Nurmi, golang-nuts
I have half a dozen good uses for this!

Regards,

Brian Ketelsen

Wolfgang Grieskamp

unread,
Nov 19, 2011, 3:24:50 PM11/19/11
to Brian Ketelsen, Evan Shaw, James Nurmi, golang-nuts
Hi James,

I actually have been working on something similar lately. Just like you, I have it lying around there and need to thoroughly test then get it through Google's internal open sourcing process (which shouldn't be a big deal).

To compare notes, here is what I did: I wrote a SWIGed wrapper for the JNI. I then wrote a binding compiler which produces Go code which provides a typesafe access to Java objects. Via Go interfaces, I'm capable of representing Java's type system quite adequately. Suppose

   class C { void m(); }
   class D extends C { void f(); }

... there will be roughly the following in Go:

    type C interface {
        M();
    }
    type D interface {
         M();
         N();
    }
    type Repr_Of_C struct {
       Repr_Of_Object
    }
    func (x Repr_Of_C) M { 
        // JNI call
    }
    type Repr_Of_D struct {
       Repr_Of_D
    }
    func (x Repr_Of_D) N {
       // JNI call
    }

Go's type system will be able to do the magic to down- and upcast just as in Java. 

A shiny detail is that the binding compiler is bootstrapped: its a Go program which uses Java reflection made available via itself to generate the binding code ;-) That required a few iterations.

However, I did run into a few subtle but hard to reproduce problems when running a JVM within a Go process, which I thought need to be further tracked down.  That's why I wanted to test it really deeply before releasing. Obviously, I can at least execute the reflection API, but that doesn't mean a lot. 

Ping me (with or without Cc) if you want to collaborate on this. Perhaps I can open source this before it really gets super stable.

-- 
Wolfgang

Brad Fitzpatrick

unread,
Nov 19, 2011, 3:34:32 PM11/19/11
to Wolfgang Grieskamp, Brian Ketelsen, Evan Shaw, James Nurmi, golang-nuts
+1 on releasing early, before it's "done".  (what is ever done?)

Brian Ketelsen

unread,
Nov 19, 2011, 3:42:59 PM11/19/11
to Brad Fitzpatrick, Wolfgang Grieskamp, Evan Shaw, James Nurmi, golang-nuts
+100 from me.  I could replace an huge Rails app with Go if I can keep the evaluation engine inside that uses all of Ruby's dynamic glory (via JRuby)

Where can I sign up?

James Nurmi

unread,
Nov 22, 2011, 11:05:32 AM11/22/11
to Brian Ketelsen, Brad Fitzpatrick, Wolfgang Grieskamp, Evan Shaw, golang-nuts
Sorry for the silence, I really wanted to get some a generic JNI
Native callback structure to work (and now they do, with about a
million caveats)

https://github.com/abneptis/GoJVM

Straight CGo & C, no Swig (though after getting it to work, I'm not
wholly certain thats a good thing <g>).

(Goinstall will fail, but if you clone and run 'make java_classes',
the rest should build fine)

I hope it does someone else some good :)

-James

Chris Lowth

unread,
Oct 30, 2014, 7:12:49 PM10/30/14
to golan...@googlegroups.com
What are the correct commands to build the gojvm module?

A simple "go build" complains about missing "gojvm/types".

By adding symlinks I get around this error, but then we have issues with the location of the libjvm.

By editing .go files I can get round that, but then I get duplicate definitions for functions like vmAttachCurrentThread, etc.

The more edits I make, the more I feel as if I am missing the simple "right" way to do this.

Any hints would be most welcome

Chris
Reply all
Reply to author
Forward
0 new messages