How can I override a java class function using Jpype? - java

I am studying python and I am using python 3.5 with the Jpype module.
The issue I am running into is that I want to override a function that was made in Java from python.
My Java Code:
package test;
public class TestApi
{
public void processMessage() {}
}
I compiled the java code to the jar file, TestApi.jar, and then I used the Jpype module in python in order to load it the class in my python script.
Here is my python code:
from jpype import *
jvmpath = getDefaultJVMPath()
startJVM(jvmpath, "-ea", ("-Djava.class.path=TestApi.jar"))
TestApiClass = JClass("test.TestApi") #i can read java class
javaApi = TestApiClass()
def PythonApi():
print("hello world")
With this code I would like to override the proccessMessage function from the class in Java using the PythonAPI function in my python code. Is this possible? and if it is how can this be done?

Related

Script engine giving error when evaluating Scala script in Java

I have a app that executes scala scripts that get passed to it. The following is an example of how I am attempting to execute the scala code.
String script = "println(\"Hello World!\")";
ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("scala");
scriptEngine.eval(script);
I get the following error.
[init] error: error while loading Object, Missing dependency 'object scala in compiler mirror', required by /Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home/jre/lib/rt.jar(java/lang/Object.class)
Failed to initialize compiler: object scala in compiler mirror not found.
** Note that as of 2.8 scala does not assume use of the java classpath.
** For the old behavior pass -usejavacp to scala, or if using a Settings
** object programmatically, settings.usejavacp.value = true.
I am using Java 7 (jdk1.7.0_80.jdk) on a Mac. I am running this from within a spring-boot app.
Scala maven dependency used.
<dependency>
<groupId>org.apache.clerezza.scala</groupId>
<artifactId>script-engine</artifactId>
<version>1.0.0</version>
</dependency>
Why am I getting this error?
We need to import and initialize the script engine like this:
import javax.script.*;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class TestScript {
public static void main(String... args) throws Exception {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("scala");
...
With ScriptEngineManager().getEngineByName("scala") a matching script engine is looked up. This just gives us the engine but not the required libraries and hooks to really execute a script.
There is one thing to note about the way Scala loads the required standard classes for the JVM. In case of the execution of scala standard Scala libraries are placed in the classpath of the JVM. This would not be the case here. You can read this for a reference. Trying to run a sample class would result in the following exception:
reflect.jar:. TestScript
[init] error: error while loading Object, Missing dependency 'object scala in compiler mirror', required by /Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/rt.jar(java/lang/Object.class)
Failed to initialize compiler: object scala in compiler mirror not found.
** Note that as of 2.8 scala does not assume use of the java classpath.
** For the old behavior pass -usejavacp to scala, or if using a Settings
** object programmatically, settings.usejavacp.value = true.
Exception in thread "main" scala.reflect.internal.MissingRequirementError: object scala in compiler mirror not found.
We can work around this by using the scala java tools helping us to load the standard Scala libraries into the JVM classpath. This is one way to make our Scala script work:
import javax.script.*;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import scala.tools.nsc.interpreter.IMain;
import scala.tools.nsc.settings.MutableSettings.BooleanSetting;
public class TestScript {
public static void main(String... args) throws Exception {
....
((BooleanSetting)(((IMain)engine).settings()
.usejavacp())).value_$eq(true);
....
The other is to simply execute the code with the following option:
$ java -Dscala.usejavacp=true ...
The complete script is this:
import javax.script.*;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import scala.tools.nsc.interpreter.IMain;
import scala.tools.nsc.settings.MutableSettings.BooleanSetting;
public class TestScript {
public static void main(String... args) throws Exception {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("scala");
((BooleanSetting)(((IMain)engine)
.settings().usejavacp()))
.value_$eq(true);
String testScript = "var a:Int = 10";
engine.eval(testScript);
String testScript2 = "println(a)";
engine.eval(testScript2);
String testScript3 = "println(a+5)";
engine.eval(testScript3);
}
}
Compiling and running this is pretty straight forward as we need the Scala libraries in the classpath.
Compiling:
$ javac -cp /Users//hkropp/bin/scala-2.11.7/lib/scala-library.jar:\
/Users//hkropp/bin/scala-2.11.7/lib/scala-compiler.jar:\
/Users//hkropp/bin/scala-2.11.7/lib/scala-reflect.jar \
TestScript.java
Running:
$ java -Dscala.usejavacp=true \-cp /Users//hkropp/bin/scala-2.11.7/lib/scala-library.jar:\
/Users//hkropp/bin/scala-2.11.7/lib/scala-compiler.jar:\
/Users//hkropp/bin/scala-2.11.7/lib/scala-reflect.jar:. \
TestScript
10
15

Using jar from scala project from python via Py4j

I have built a jar from my Scala project.
I have the following structure for what I want to use from this jar
package aaa.bbb.ccc
case class FooResult(...)
trait Foo(...) {
def bar(): FooResult
}
object Foo {
private class FooImpl(...) extends Foo {
...
}
def apply(...): Foo
}
First question: Maybe I have misunderstood something in what Py4J offers,
but do I have to write a java/scala class to start the Py4J gateway if I want to use my own classes? Or is it enough to add it to the gateway's jvm's classpath?
Second question (which I guess doesn't apply depending on the answer to above): How do I add my jar when starting the java gateway in order to make it available? To solve this temporarily, I just started the jvm manually with my jar along with the Py4J jar with this command
java -classpath "path/to/py4j.jar:path/to/my.jar" py4j.GatewayServer 0
and then connected to it manually from the Python code. Then I tried to import my classes via
java_import(gateway.jvm, "aaa.bbb.ccc.*")
which didn't throw any error but I'm not sure it worked because it doesn't throw any error if I input some fake classpath.
Third question (which applies if the answer to the first is that I have to write the entry point to access my classes): How does this work when using scala?
object Main extends App {
val gw = new GatewayServer(// TODO: how to expose my classes here?
}

Access C# method in DLL from Java

I'm having trouble trying to call a function writed in C# from Java. I have already loaded the dll that contains the function.
Error message:
java.lang.UnsatisfiedLinkError: app.clsValidation.validate(Ljava/lang/String;)Ljava/lang/String;
C# code compiled into a 64-bit dll:
namespace library {
public class clsValidation {
public string validate(string txt) {
return txt;
}
}
}
Java code
The class:
package app;
public class clsValidation {
static {
System.loadLibrary("library");
}
public native String validate(String txt);
}
How I'm calling it in Java:
String txt = "something";
String result = new clsValidation().validate(txt);
That's to be expected. Your Java code treats the C# DLL as if it were an unmanaged library. It is not. It does not export unmanaged functions that can be imported using LoadLibrary and GetProcAddress.
If you wish to export unmanaged functions from your .net DLL then you can:
Use Robert Giesecke's UnamanagedExports to do so.
Make a mixed mode C++/CLI assembly which exports unmanaged functions.
Other options would include exposing the functionality through COM which is readily consume from Java.

Not able to load my custom java classes in JRuby

I have created one java project. Folder structure is like
Test
- src
-TestJavaCall.java
I created jar of this prject test.jar.
Code in my ruby file is as follows.
include Java
require '/home/office/test.jar'
java_import Java::TestJavaCall
testJava = TestJavaCall.new
When i am executing this script, i am getting this error.
NameError: cannot link Java class TestJavaCall
get_top_level_proxy_or_package at org/jruby/javasupport/JavaUtilities.java:49
const_missing at file:/home/spaul/.rvm/rubies/jruby-1.7.4/lib/jruby.jar!/jruby/java/java_module.rb:4
Please let me know what is the way to use custom java classes in ruby?
Source code of TestJavaCall.java
public class TestJavaCall {
public void testJavaCall()
{
System.out.println("test java call");
}
}

Scala Import and Packages error

I want to import and call a java class(which in from an external package ) from a scala object . My code is like this
Java code:
package com.test.services.account;
public class MyMain {
public static void main(String[] args) {
System.out.println("coming into main");
}
}
Scala code:
package com.newtest.newservice.scala
import _root_.com.test.services.account.MyMain
object scalatest {
def main(args: Array[String]) {
println("Hello, world! " + args.toList)
// Deployer.main(args)
val de:MyMain = new MyMain()
println(de.toString())
}
}
when i compile it using scalac scalatest.scala, it gives an error
scalatest.scala:2: error: object test is not a member of package com
import root.com.test.services.account.MyMain
^
one error found
Could anybody guide me how can i import my java class into scala code ?
Thanks
Suresh
If you don't want to use something like sbt, you should first decide where your CLASSPATH is. Since you have two different class files (one generated from Java and one from Scala), you need at least one directory where your class files need to live. Let's say that is d:\myclasses.
In that case, you'd compile the java file using this command:
d:\mycode> javac -d d:\myclasses MyMain.java
This would generate your Java class file in the appropriate package structure at d:\myclasses. Then you would compile the scala file like so
scalac -classpath d:\myclasses -d d:\myclasses scalatest.scala
Instead of passing the classpath as part of the scalac command line, you could also set your CLASSPATH environment variable to d:\myclasses.

Categories

Resources