#1799 Help with Java FFI

Pueo Thu 1 Mar 2012

I'm having trouble with the Java FFI. I want to use Jade.jar as an external library, and this is what I have so far:

My pod folder it set up:

Pod/
  build.fan
  fan/
    Main.fan
  java/
    Jade.jar

Jade.jar is set up:

Jade/
  core/
    Actor.class
    [etc]
  fov/
    [etc]
  gen/
    [etc]
  path/
    [etc]
  ui/
    [etc]
  util/
    [etc]
META-INF/
  MANIFEST.MF

Build.fan states:

using build

class Build : build::BuildPod
{
  new make()
  {
    podName = "Pod"
    summary = "Pod Pod"
    srcDirs = [`fan/`]
    javaDirs = [`java/`]
  }
}

Main.fan states:

using [java] Jade.core.Actor

class Main
{
  public Void main
  {   
    echo("Pod")
  }
}

From what I read, Jade.core.Actor should map to Jade/core/actor.class, however, I get a "Java package "Jade.core.Actor" not found" error when I try to build the pod. I have no idea what's wrong.

SlimerDude Thu 1 Mar 2012

Try

using [java] Jade.core::Actor

brian Thu 1 Mar 2012

Also we don't support using Java FFI on yourself - so you should build jade.jar as a pod by itself and then have your pod depend on it. Or just stick jade.jar in "lib/java/ext"

Pueo Thu 1 Mar 2012

@SlimerDude: When I try that, I get "Java package "Jade.core" not found"

@brian: I do have jade.jar in lib/java/ext as well, so I'm not sure what the problem is there. Should jade.jar be all lowercase, because now it's "Jade.jar". How do I compile Jade.jar as a pod?

brian Thu 1 Mar 2012

If you have the jar in lib/java/ext then it should be in your classpath. You can check by running:

fan compilerJava::ClassPath

You should see:

  1. "Jade.core" listed under packages (with number of classes)
  2. your Jar listed in files

Pueo Thu 1 Mar 2012

@brian:

  1. Yes, 5 classes, which is right
  2. Yes, with the right URI

brian Thu 1 Mar 2012

If your classpath is setup (which it sounds like it is), then this script should compile:

using [java] Jade.core
class Main
{
  public Void main
  {   
    echo(Actor#)
  }
}

Pueo Thu 1 Mar 2012

If I copy/paste that, I still get a Java package "Jade.core" not found error. When I dump the class paths, Jade.core is lowercase (jade.core), and when I try that:

using [java] jade.core **lowercase, not Jade.core
class Main
{
  public Void main
  {   
    echo(Actor#)
  }
}

I get Expected "class", not "using"

KevinKelley Thu 1 Mar 2012

using [java] jade.core

class Main
{
  Void main()
  {   
    echo(Agent#)
  }
}

works... Agent, in jade.core, not Actor, at least in the jade I'm looking at...

>fan test.fan
[java]jade.core::Agent

Pueo Thu 1 Mar 2012

I don't think that's the jade I'm working with. I actually renamed it, it was originally JadeRogue.jar. Could that have broken it?

KevinKelley Thu 1 Mar 2012

Nah, but look inside your jar and make sure there's a directory structure that matches the package name, and that there's an Actor.class file in the jade/core/ directory...

Note the previous example forgot the parens on the main method.

Also note that it should be

using [java] jade.core::Actor

or just

using [java] jade.core

to import the whole package.

Pueo Thu 1 Mar 2012

Yeah, there is an Actor.class file in jade/core, and the structures match, that's why I'm confused, I don't see anything wrong.

KevinKelley Thu 1 Mar 2012

Do you know that it's a public class? What error do you now get with that last example?

Pueo Thu 1 Mar 2012

I do not know what kind of class it is, my last error, with using [java] jade.core::Actor is Expected "class", not "using".

KevinKelley Thu 1 Mar 2012

I remember an old parse bug in using statement, worked-around by changing to

using [java] jade.core::Actor as Actor

for example. That error message looks like parsing is breaking there, for some reason...

KevinKelley Thu 1 Mar 2012

fwiw, I just grabbed JadeRogue.jar from google and dropped it in my lib/java/ext, and the example worked.

>fan test.fan
[java]jade.core::Actor

So I don't know what's up. OS, JVM version, Fantom version? What does

fan -version

report?

Pueo Thu 1 Mar 2012

Meh, even with as Actor it still throws the same error.

Oh, also:

Pueo:~ Pueo$ fan -version
Fantom Launcher
Copyright (c) 2006-2011, Brian Frank and Andy Frank
Licensed under the Academic Free License version 3.0

Java Runtime:
  java.version:    1.6.0_29
  java.vm.name:    Java HotSpot(TM) 64-Bit Server VM
  java.vm.vendor:  Apple Inc.
  java.vm.version: 20.4-b02-402
  java.home:       /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
  fan.platform:    macosx-x86_64
  fan.version:     1.0.61
  fan.env:         sys::BootEnv
  fan.home:        /Users/Pueo/.fantom

Huh. I'm .1 version behind. Well, updated to 1.0.62, same error with same code.

KevinKelley Thu 1 Mar 2012

I'm on Windows, have checked w/ both 1.0.61 and 1.0.62 that the example works. Also it works whether I do it as a script or thru a build.fan structured like yours.

So, I dunno. This is dead plain basic, ought to work stuff. The jar has no native code, just plain old java classes.

That Expected "class", not "using" error is bugging me. Can I see your file, that causes it? That shouldn't happen, there.

Pueo Thu 1 Mar 2012

Ok, here: http://dl.dropbox.com/u/62116165/FFI%20Help.zip

fantom/ is my home folder for fantom files.

jade/ is my reference for using jade.jar

jade.jar is the actual .jar file

Pod/ is my pod folder

KevinKelley Thu 1 Mar 2012

Not getting that same error... I went into your Pod dir and ran fan build.fan and had two errors:

  • the main method in Main.fan missing ()
  • no source files in the javaDir

so I added the one and commented out the other, and it compiles and runs okay.

The javaDirs prop is intended for java source, that needs to be compiled by javac... there's a resDirs prop for things like resources that you want to have included in the pod file.

Make those two files look like this, then try again.

Main.fan

using [java] jade.core::Actor

class Main
{
  public Void main()
  {   
    echo(Actor#)
  }
}

build.fan:

using build

class Build : build::BuildPod
{
  new make()
  {
    podName = "Pod"
    summary = "Pod Pod"
    srcDirs = [`fan/`]
  }
}

Pueo Thu 1 Mar 2012

Ok, it worked, not sure why it was having trouble before, thanks a lot :)

I think I figured out the problem, I had comments above the code, as seen in http://fantom.org/doc/docLang/Conventions.html#comments, as soon as I took those out, it worked. Not sure why.

KevinKelley Fri 2 Mar 2012

That's one that's bit me before; fandoc style ** comments aren't like plain comments, and can only appear in proper place: start of class, start of method or field.

Anyway, good luck! I got interested by the JadeRogue subject -- if I ever disappear, look for my bones around level 79 of Angband...

Pueo Fri 2 Mar 2012

Oh, thanks a lot! I hadn't realized they were "special" comments, I figured it was just a stylistic difference. No wonder I was getting expected "class", not "using" And wow, level 79, nice job :P

brian Fri 2 Mar 2012

Yes they are special comments since they are parsed as part of the AST. That is definitely sort of a gotcha. I pushed a fix to have parser skip those comments if used before using statements.

Login or Signup to reply.