I couldn't find a solution create a polyglot source out of multiple files in GraalVM.
What exactly I want to achieve:
I have a python project:
my-project:
.venv/
...libs
__main__.py
src/
__init__.py
Service.py
Example sourcecode:
# __main__.py
from src.Service import Service
lambda url: Service(url)
# src/Service.py
import requests
class Service:
def __init__(self, url):
self.url = url
def invoke(self):
return requests.get(self.url)
This is very simple example, where we've got an entry-point script, project is structured in packages and there is one external library (requests).
It works, when I run it from command-line with python3 __main__.py, but I can't get it work, when embedding it in Java (it can't resolve imports).
Example usage in java:
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Source;
import org.graalvm.polyglot.Value;
import java.io.File;
import java.io.IOException;
public class Runner {
public static void main(String[] args) throws IOException {
Context context = Context.newBuilder("python")
.allowExperimentalOptions(true)
.allowAllAccess(true)
.allowIO(true)
.build();
try (context) {
// load lambda reference:
Value reference = context.eval(Source.newBuilder("python", new File("/path/to/my-project/__main__.py")).build());
// invoke lambda with `url` argument (returns `Service` object)
Value service = reference.execute("http://google.com");
// invoke `invoke` method of `Service` object and print response
System.out.println("Response: " + service.getMember("invoke").execute());
}
}
}
It fails with Exception in thread "main" ModuleNotFoundError: No module named 'src'.
The solution works for javascript project (having similar index.js to __main__.py, its able to resolve imports - GraalVM "sees" other project's files, but somehow it doesn't, when using python.
I found out, that python is able to run zip package with project inside, but this also doesn't work with GraalVM.
Is there any chance to accomplish it? If not, maybe there is a similar tool to webpack for python (if I could create a single-file bundle, it should also work).
Btw, I don't know python at all, so I may missing something.
Thanks for any help!
Related
Here is my Java library (.aar) file's code.
package com.sahib.ffpy;
import com.arthenica.ffmpegkit.FFmpegSession;
import com.arthenica.ffmpegkit.FFmpegKit;
public class ffpy<command>
{
public static void Run(final String command) {
final FFmpegSession session = FFmpegKit.execute(command);
}
}
This is supposed to take a command and execute in FFmpegKit by ARTHENICA.
I am using this library with pyjnius to run it as I can not directly do.
FFmpegSession session = FFmpegKit.execute(command)
In python.
This is how my python code looks:
FFMPEG = autoclass('com.sahib.ffpy.ffpy')
FFMPEG.Run("-i "+INPUT_FILE+" -qscale:v "+str(FRAME_QUALITY)+" TEMP/frame%06d.jpg -hide_banner")
I am using Kivy/Buildozer.
Here are the Gradle dependencies in buildozer:
android.add_aars = ffpy-debug.aar
android.gradle_dependencies = "com.arthenica:ffmpeg-kit-full:5.1"
I have tried extracting the classes.jar from both ffmpegkit and this and combining them, which throws a different error (I know it's not the right way to do it). I tried building ffmpegkit myself. I have tried directly using FFmpeg Kit in Python, but I don't think it will work.
So I want to make a java application in eclipse which the user i will be able to import .zip files. Each .zip file will represent a cat breed. I will click on a "train" button and my program will contact IBM Watson services and create a classifier. Then from a different window, i will import random cat images and the program will show what cat breed is in the image. Everything with the SDKs is fine since I ran some examples from the official Watson site and everything ran smoothly. Problem comes when I try to create my own classifiers. The code you are about to see is also from their site. For some reason the createClassifier method won't take the CreateClassifierOptions object as an argument.
import java.io.File;
import com.ibm.watson.developer_cloud.http.ServiceCall;
import com.ibm.watson.developer_cloud.speech_to_text.v1.model.RecognitionCallback;
import com.ibm.watson.developer_cloud.visual_recognition.v3.*;
import com.ibm.watson.developer_cloud.visual_recognition.v3.model.*;
public class TrainningClassifier{
public static void main(String[] args) {
VisualRecognition service = new VisualRecognition(
VisualRecognition.VERSION_DATE_2016_05_20
);
service.setApiKey("aca4433597018de62edafdeebceb2bdc1482496a");
CreateClassifierOptions createClassifierOptions = new CreateClassifierOptions.Builder()
.name("dogs")
.addClass("beagle", new File("./beagle.zip"))
.addClass("goldenretriever",new File("./golden-retriever.zip"))
.addClass("husky", new File("./husky.zip"))
.negativeExamples(new File("./cats.zip"))
.build();
Classifier dogs = service.createClassifier(createClassifierOptions).execute();
System.out.println(dogs); /*error is in the above line.
the createClassifier method.*/
}
}
Error: Exception in thread "main" java.lang.Error: Unresolved
compilation problem: The method createClassifier(ClassifierOptions)
in the type VisualRecognition is not applicable for the arguments
(CreateClassifierOptions)
at testVisualRec.ForAssignment.main(ForAssignment.java:31)
Any ideas?
Found the solution. For some reason eclipse wouldn't recommend this solution I had to experiment. I just added throws IOException in main method. I also put inside the main method System.out.println(new File(".").getAbsoluteFile()); to make sure the path was correct, and it was. (SDK used for this project is 4.0.0, not the newest one. SDK found here: https://github.com/watson-developer-cloud/java-sdk/releases)
I am trying to use graphviz native library from java.I am able to compile the program in Eclipse. But getting exception:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no gv in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1681)
at java.lang.Runtime.loadLibrary0(Runtime.java:840)
at java.lang.System.loadLibrary(System.java:1047)
at org.graphviz.test.Test.<clinit>(Test.java:12)
Could not find the main class: org.graphviz.test.Test. Program will exit.
Here is my code(copied from somewhere of course):
package org.graphviz.test;
import org.graphviz.internal.SWIGTYPE_p_Agedge_t;
import org.graphviz.internal.SWIGTYPE_p_Agnode_t;
import org.graphviz.internal.SWIGTYPE_p_Agraph_t;
import org.graphviz.internal.gv;
public class Test {
static {
System.loadLibrary("gv");
}
public static void main(String[] args) {
SWIGTYPE_p_Agraph_t g, sg;
SWIGTYPE_p_Agnode_t n, m;
SWIGTYPE_p_Agedge_t e;
g = gv.digraph("G");
System.out.println(gv.setv(g,"aaa","xxx"));
System.out.println(gv.getv(g,"aaa"));
sg = gv.graph(g,"SG");
n = gv.node(g,"hello");
System.out.println(gv.getv(n,"label"));
System.out.println(gv.setv(n,"aaa","xxx"));
System.out.println(gv.getv(n,"aaa"));
m = gv.node(g,"world");
System.out.println(gv.getv(m,"aaa"));
e = gv.edge(n,m);
System.out.println(gv.setv(e,"aaa","xxx"));
System.out.println(gv.getv(e,"aaa"));
gv.rm(e);
gv.rm(n);
gv.rm(m);
gv.rm(g);
g = gv.readstring("digraph G {a->b}");
gv.rm(g);
g = gv.read("hello.gv");
gv.layout(g,"dot");
gv.render(g,"png","hello.png");
gv.rm(g);
}
}
I have pointed the library correctly, but at runtime getting UnsatisfiedLinkError. Any one ever tried using the graphviz native library?Please let me know how to configure JNI.
I believe you're problem is that you are trying to import from gv, but you aren't specifying what you want to import. It's kind of like if you were to just write ---
import org.graphviz.internal;
Instead, try importing a specific library from the gv library. For example, if you want a directed graph, you would probably do something like this ---
import org.graphviz.internal.gv.digraph;
Take a look at the following document and see if it helps at all. It might give you a better idea of where gv comes from and how you can import the methods associated with it.
http://www.graphviz.org/pdf/gv.3java.pdf
Get graphviz-java
Make sure you have graphviz-java installed. For MacPorts this should work like this:
sudo port install graphviz +java
This actually failed for me on the first try and complained about swig-java, this fixed it:
sudo port install swig-java
sudo port install graphviz +java
Now the library is installed under /opt/local/lib/graphviz/java for me, search for libgv.jnilib if you don't find it there.
Setup class path
I compiled in Eclipse, for that I added /opt/local/lib/graphviz/java to the build path as an external class folder.
Compile
This is a simple example that writes an image. Note that System.loadLibrary("gv") must happen before calling anything in graphviz.
import org.graphviz.SWIGTYPE_p_Agedge_t;
import org.graphviz.SWIGTYPE_p_Agnode_t;
import org.graphviz.SWIGTYPE_p_Agraph_t;
import org.graphviz.gv;
public class Main {
static {
System.loadLibrary("gv");
}
public static void main(String[] args) {
SWIGTYPE_p_Agraph_t g = gv.digraph("G");
SWIGTYPE_p_Agnode_t n = gv.node(g, "hello");
SWIGTYPE_p_Agnode_t m = gv.node(g, "world");
SWIGTYPE_p_Agedge_t e = gv.edge(n, m);
gv.layout(g, "dot");
gv.render(g, "png", "hello.png");
}
}
Run
Run with java.library.path=/opt/local/lib/graphviz/java, e.g. -Djava.library.path=/opt/local/lib/graphviz/java as VM arguments in an Eclipse run configuration.
I have developed a java class exported into a .jar library that will be called by a Pentaho Kettle 'modified java script'. The .jar is compiled in Eclipse with JDC Compliance level 1.7.
When I try to use this class inside a 'modified java script', I get the error: ReferenceError: “xeroCallPackage” is not defined. I have tried lots of things without much luck so far.
My file xeroCallPackage.jar is in the path with the other *.jar files in Pentaho (..\data-integration\lib)
For info:
The stripped down (for simplicity) java library code is here:
package xeroCallPackage;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.Map;
public class xeroURLCall {
public String getResponse(String CONSUMER_KEY, String CONSUMER_PRIVATE_KEY, String URL) throws IOException, OAuthException, URISyntaxException {
// stripped out code here
return response.readBodyAsString();
}
}
The stripped down Pentaho 'modified java script' is here:
var CONSUMER_KEY = "ffffff";
var CONSUMER_PRIVATE_KEY = "aaaaa";
var URL = "https://gggggggg.rrrrr.wwww";
var ResponseAsString;
ResponseAsString = new xeroCallPackage.xeroURLCall.getResponse(CONSUMER_KEY,CONSUMER_PRIVATE_KEY,URL);
You will either have to have org as top-most package or prefix the fully qualified name of your class with Packages.
So in your case the fully qualified name of your class that can be used for calling from Spoon will be Packages.xeroCallPackage.xeroURLCall
Apart from that the supplied JavaScript code won't work (but maybe that's just because of the stripped down code). You'd have to create a xeroURLCall object first and then call the getResponse method on that object:
var call = new Packages.xeroCallPackage.xeroURLCall(...);
var responseAsString = call.getResponse(CONSUMER_KEY,CONSUMER_PRIVATE_KEY,URL);
I'm discovering the jni4net. This is the technology used to provide the bridge between Java and .NET. So, I created new Eclipse Java project and copied the sample code from jni4net-0.8.6.0-bin/samples/myCSharpDemoCalc->MyCalcUsageInJava.java into this project. However the code cannot be compiled because two imports "mycsharpdemocalc.DemoCalc" and "mycsharpdemocalc.ICalc" cannot be found. I don't understand how to integrate/import mycsharpdemocalc.c into the Java project so that the code could be compiled.
import net.sf.jni4net.Bridge;
import java.io.IOException;
import mycsharpdemocalc.DemoCalc;
import mycsharpdemocalc.ICalc;
public class MyCalcUsageInJava {
public static void main(String arsg[]) throws IOException {
Bridge.init();
Bridge.LoadAndRegisterAssemblyFrom(new java.io.File("MyCSharpDemoCalc.j4n.dll"));
ICalc calc = new DemoCalc();
final int result = calc.MySuperSmartFunctionIDontHaveInJava("Answer to the Ultimate Question of Life, the Universe, and Everything");
System.out.printf("Answer to the Ultimate Question is : " + result);
}
}
There is ReadMe in each sample directory.
You have to use proxygen tool to generate the proxies (which are used in the java code).
There is generateProxies.cmd batch to do that.
More complex things may need config file for proxygen.
Also there is community Wiki