ocamljava icon indicating copy to clipboard operation
ocamljava copied to clipboard

Support for classpath resolution of jar resources

Open struktured opened this issue 9 years ago • 5 comments

I am limited by the fact that ocamljava requires all jars to be co-located in the same library folder. Could parameters be added to override this so it's resolved from a classpath location instead?

This is the error:

java -cp /folder1/ocamljava.jar:/folder2/ocaml-lib-files.jar:/folder3/ocamlrun.jar ocaml.compilers.ocamljavaMain javalib.cmja -java-extensions -I ... -c ... company.ml File "company.ml", line 1: Error: Cannot compute stack frames for create_private_company_1012 ("/ocamljava-2.0-alpha1/lib/ocaml/ocamlrun.jar" does not exist)

In java, I am suggesting something along the lines of this to load resources (rather than a file system path as it appears to be now):

http://stackoverflow.com/questions/1900154/classpath-resource-within-jar

struktured avatar Aug 04 '14 04:08 struktured

Well, the resource mechanism is already used in OCaml-Java. For example, when using the binary distribution, files from the standard library (e.g. stdlib.cmja) are actually loaded from the jar file named ocaml-lib-files.jar. This archive contains all the files that would be installed in $PREFIX/lib/ocaml if using a source distribution.

That being said, I am afraid I do not understand the problem you encounter. Could you elaborate on what you are trying to achieve?

Also, why are you executing java -cp ... ocaml.compilers.ocamljavaMain -I ... -c ... rather than ocamljava -I ... -c ...?

xclerc avatar Aug 11 '14 19:08 xclerc

I am using a build system (Maven) with particular requirements- it requires that each dependency of the build system is bundled together into a single unit (usually a jar), which is then placed in a single folder. It is somewhat like opam but a bit more restrictive. The file system layout looks something like this:

$HOME/.m2/repository/org/ocamljava/ocamljava/2.0-alpha2/ocamljava-2.0-alpha2.jar $HOME/.m2/repository/org/ocamljava/ocaml-lib-files/2.0-alpha2/ocaml-lib-files-2.0-alpha2.jar $HOME/.m2/repository/org/ocamljava/ocamlrun/2.0-alpha2/ocamlrun-2.0-alpha2.jar

My goal is to delegate to this build system to load ocamljava related dependencies into the classpath as necessary. This essentially boils down to invoking java with the "-cp" argument and passing the above the jars separated by a ":" (shown in my previous comment).

However, this does not work as your library requires that all jars are located in a specific well known absolute path (the -prefix arg passed to your configure script). I noticed though that the path location is irrelevant- what your code implicitly requires is that all the jars are located in the same folder (but not necessarily the -prefix specified folder).

One solution might be this: where your code does something like getResource("/foo/bar/some-lib.jar") to access "some-code.class", it instead needs a mode where the jars are already assumed to be on the classpath, and it invokes getResource("some-file.class") directly.

I'm open to other ideas as well- I'm even willing to add this feature myself, but I'm pretty sure this code is in the closed source java portion of your library.

struktured avatar Aug 11 '14 22:08 struktured

Another solution that would be adequate for me is if there was a system property I could pass to the JVM to independently specify the locations of ocamlrun, ocaml-lib-files, and ocamljava (possibly others, but at least those jars).

struktured avatar Aug 12 '14 16:08 struktured

However, this does not work as your library requires that all jars are located in a specific well known absolute path (the -prefix arg passed to your configure script).

Not really, as you can install the binary distribution in any directory. The jar files of the compilers (e.g. lib/ocamljava.jar) only contain a Class-Path information (in entry META-INF/MANIFEST) that points to ocaml-lib-files.jar.

I may be sufficient to just patch this information in the manifest to fix your problem. Could you try?

Another solution that would be adequate for me is if there was a system property I could pass to the JVM to independently specify the locations of ocamlrun, ocaml-lib-files, and ocamljava (possibly others, but at least those jars).

The thing is that the offending file (/ocamljava-2.0-alpha1/lib/ocaml/ocamlrun.jar) is to be loaded from ocaml-lib-files.jar using the resource mechanism. Its path is hard-coded in the compiler (following the convention set by the original OCaml compilers). I am a bit reluctant to change this, as it would let the user shoot himself in the foot way to easily...

xclerc avatar Aug 12 '14 17:08 xclerc

Changing the Class-Path entry in ocamljava.jar had no visible effect. Created like this:

jar xvf ocamljava.jar

The manifest

Class-Path: /foobar Main-Class: ocaml.compilers.ocamljavaMain

Recreate jar:

jar cfm ocamljava.jar MANIFEST.MF fr META-INF/ ocaml/ org/

Now here's the simplest example of the error once more, with this jar:

ls code.ml ocamljava.jar ocaml-lib-files.jar
java -cp ocaml-lib-files.jar:ocamljava.jar ocaml.compilers.ocamljavaMain code.ml File "code.ml", line 1: Error: Cannot compute stack frames for f_1008 ("/ocamljava-2.0-alpha1/lib/ocaml/ocamlrun.jar" does not exist)

To clarify what I mean that your library depends on a relative path location is the following:

ls code.ml ocamljava.jar ocaml-lib-files.jar ocamlrun.jar
java -cp ocaml-lib-files.jar:ocamljava.jar ocaml.compilers.ocamljavaMain code.ml

No errors, here, but same exact command as before. Note this would also work if the jars were installed in some other arbitrary folder, opposed to the current directory, as long as ocamlrun.jar is present too in that directory. But if you try to put ocamlrun.jar elshwhere...

mkdir temp mv ocamlrun.jar temp/ java -cp ocaml-lib-files.jar:ocamljava.jar:temp/ocamlrun.jar ocaml.compilers.ocamljavaMain code.ml File "code.ml", line 1: Error: Cannot compute stack frames for f_1008 ("/ocamljava-2.0-alpha1/lib/ocaml/ocamlrun.jar" does not exist)

If I could get that last example to work, in that that the location of ocamlrun.jar is resolved strictly through the "-cp" argument (not via the path relative to the ocamljava.jar, or the path according to the -prefix argument), then I would be good to go.

struktured avatar Aug 22 '14 02:08 struktured