#468 Using third-party Java libraries

mcarter Wed 18 Feb 2009

Could someone tell me how I can use a third-party java library such as Joda in fan.

I tried making the CLASSPATH include the required jar file and it does not seem to do the trick.

Here is a simple example of what I am trying to do:

using [java] java.util::Date as JDate
using [java] org.joda.time::Duration as JDuration

class Hello
{
  static Void main() { 
     a := JDate()
     echo("hello world #2") 
     echo(a.toString())
  }
}

The second line results in an error message when I try to run it:

hello.fan(2,1): Java package org.joda.time not found ERROR: cannot compile script

I read about FFI and not sure if that will resolve the problem.

Obvious newbie question here. Any help would be much appreciated. Thanks in advance.

brian Wed 18 Feb 2009

You will need to setup your classpath to include the jar file: http://fandev.org/doc/docLang/JavaFFI.html#classpath

I haven't messed around with CLASSPATH env variable, so simplest thing is to stick the jar in your lib/ext for now

mcarter Thu 19 Feb 2009

That works. Thanks.

It would still be preferable to set the CLASSPATH explicitly and not have to throw the jar files in the lib/ext directory.

It appears that fan is ignoring the CLASSPATH env variable and is building the java.class.path system variable upon startup based on the jars it finds in "its" lib/java/ext/win directory. That is where I had to put my jar files for fan to pick up automatically.

It works, but it is not optimal.

brian Thu 19 Feb 2009

I agree, the bash scripts need some work.

If you wish to help fix the bash scripts please let me know. They are broken for bootstrap build b/c of the FAN_HOME environment variable. And I agree we should also CLASSPATH.

mcarter Sun 22 Feb 2009

Brian,

I am sure you know more about the system than I do. So it might be the bash scripts that need some work. I suspect that the target OS for that would be cygwin, darwin or linux. What about the Windows environment? Is there a script that launches fan. I was under the impression that I was launching the exe directly.

What if we modified launcher/java.cpp ? The initOptions() function makes calls such as:

addExtJars(optClassPath, "lib\\java\\ext");
addExtJars(optClassPath, "lib\\java\\ext\\win");

What if we picked up the CLASSPATH environment variable here using getenv() and added the discovered jars/directories in a similar manner? Wouldn't that work?

I realize that once we get the CLASSPATH via getenv() we would need to have an OS dependent way to parse the string. Windows uses ; to separate items whilst unix variants use : to separate the items in the classpath.

Unfortunately, I don't have an upto date C/C++ development environment on my machine, not sure how much I can help. Will try to help if you can provide some guidance.

brian Sun 22 Feb 2009

Windows uses the exe launchers instead of a script (since we have check the registry to find your java install)

I am not sure convention of other platforms, but does everyone agree that the win/bash launchers should pass thru CLASSPATH to the Java runtime?

cheeser Mon 23 Feb 2009

I do. Users should never, ever be asked to dump jars in jre/lib/ext.

tompalmer Mon 23 Feb 2009

Actually, I'd much rather do that than mess with CLASSPATH. I'd like my project and my Fan installation to define my environment entirely. Which is also why I'd like to have a canonical place to put things in my project and have them automatically added to the CLASSPATH.

Seems like the ability to install a jar (or dll) as a pod could also be nice, but the way to do that might be to make a new project anyway (which also provides the option for wrapping both jar and dll in a compatibility layer, if you want cross-platform).

cheeser Mon 23 Feb 2009

I'm fine with the idea of a dir to dump jars in for a project. But jre/lib/ext is system wide which presents any number of problems: different projects that need different version of libraries (xml parsers anyone?), having write access to that dir (forget user space apps then...), etc. Ultimately it's the same question of what to do with user generated pods: one global place vs project specific, etc.

brian Tue 24 Feb 2009

I kind of prefer having a "config file" which defines a Fan project versus passing a bunch of crap on the command line:

fan -proj:myproj.props somePod::Main

Also see previous discussion.

One of the issues is that Fan needs an actual directory where it can cache its type index files. This "project file" would serve lots of purposes:

  • place to put java jars
  • place to stick non-core Fan pods
  • directory to use for cache files
  • directective for IDEs "walking up the dir tree"
  • override of system props which come from env and sys.props

How do you guys feel about that direction?

mcarter Wed 25 Feb 2009

I like the idea of a config file so we can define what we need on a project basis. I am assuming that specifying the config file would be optional. If no config file is specified then defaults would apply.

tompalmer Wed 25 Feb 2009

By convention or by configuration (build.fan), I think it's important to allow 3rd-party jars/dlls to be installed as part of a pod.

Run-time properties might also be nice.

JohnDG Wed 25 Feb 2009

  1. Type database dir should be tmp dir unless no write permission (if it's slow to generate it, then maybe this wouldn't work).
  2. Backup should be memory-based type database, for Live CD distros & such.
  3. It should be possible to ship pods as Jars (Java) or DLLs (.NET), or to ship Jars or DLLs bundled into pods (Pod).
  4. Generally, a standalone Fan app would ship with everything it needs inside the pod. However, for those occasions when it is not desirable, having a default such as searching ./lib/ seems appropriate; command-line flags could also specify additional jars/dlls/pods, which would be very useful in some situations.

Login or Signup to reply.