How do I implement a Java interface in Clojure - java

How do I create a Clojure object that implements this interface and then gets called from Java code?
public interface Doer {
public String doSomethin(String input);
}
Doer clojureDoer = ?;
String output = clojureDoer.doSomethin(input);

reify is strongly preferred for implementing interfaces - proxy is heavy-duty, old, and slow, so should be avoided when possible. An implementation would look like:
(reify Doer
(doSomethin [this input]
(...whatever...)))

As of Clojure 1.6, the preferred approach would be as follows. Assuming you have, on your classpath, the Clojure 1.6 jar and the following clojure file (or its compiled equivalent):
(ns my.clojure.namespace
(:import [my.java.package Doer]))
(defn reify-doer
"Some docstring about what this specific implementation of Doer
does differently than the other ones. For example, this one does
not actually do anything but print the given string to stdout."
[]
(reify
Doer
(doSomethin [this in] (println in))))
then, from Java, you could access it as follows:
package my.other.java.package.or.maybe.the.same.one;
import my.java.package.Doer;
import clojure.lang.IFn;
import clojure.java.api.Clojure;
public class ClojureDoerUser {
// First, we need to instruct the JVM to compile/load our
// Clojure namespace. This should, obviously, only be done once.
static {
IFn require = Clojure.var("clojure.core", "require");
require.invoke(Clojure.read("my.clojure.namespace"));
// Clojure.var() does a somewhat expensive lookup; if we had more than
// one Clojure namespace to load, so as a general rule its result should
// always be saved into a variable.
// The call to Clojure.read is necessary because require expects a Clojure
// Symbol, for which there is no more direct official Clojure API.
}
// We can now lookup the function we want from our Clojure namespace.
private static IFn doerFactory = Clojure.var("my.clojure.namespace", "reify-doer");
// Optionally, we can wrap the doerFactory IFn into a Java wrapper,
// to isolate the rest of the code from our Clojure dependency.
// And from the need to typecast, as IFn.invoke() returns Object.
public static Doer createDoer() {
return (Doer) doerFactory.invoke();
}
public static void main(String[] args) {
Doer doer = (Doer) doerFactory.invoke();
doer.doSomethin("hello, world");
}
}

With proxy
See the proxy macro. Clojure Docs have some examples. It's also covered on Java Interop page.
(proxy [Doer] []
(doSomethin [input]
(str input " went through proxy")))
proxy returns an object implementing Doer. Now, to access it in Java you have to use gen-class to make your Clojure code callable from Java. It's covered in an answer to the "Calling clojure from java" question.
With gen-class
(ns doer-clj
(:gen-class
:name DoerClj
:implements [Doer]
:methods [[doSomethin [String] String]]))
(defn -doSomethin
[_ input]
(str input " went through Clojure"))
Now save it as doer_clj.clj, mkdir classes and compile it by calling in your REPL (require 'doer-clj) (compile 'doer-clj). You should find DoerClj.class ready to be used from Java in classes directory

For a more general take on this question, this diagram can be freaking useful when you are in need for some kind of Java-interop:
https://github.com/cemerick/clojure-type-selection-flowchart

If doSomethin() is defined in your interface, you should not mention it in :methods. Quote from http://clojuredocs.org/clojure_core/clojure.core/gen-class:
:methods [ [name [param-types] return-type], ...]
The generated class automatically defines all of the non-private
methods of its superclasses/interfaces. This parameter can be used
to specify the signatures of additional methods of the generated
class. Static methods can be specified with ^{:static true} in the
signature's metadata. Do not repeat superclass/interface signatures
here.

Related

Troubles overriding java method in jruby

I'm having some troubles overriding a java method from a jruby class. Since JRuby exposes java methods with both camel and snake case syntaxes, i've tried both approaches to override the same method, but i'm having strange results:
JAVA
package tabaqui;
class MyJavaClass {
public void myMethod() {
System.out.println("Java method");
}
public void invokeMyMethod() {
myMethod();
}
}
RUBY
class MyRubyClass1 < Java::tabaqui.MyJavaClass
def my_method
puts "Ruby method from MyRubyClass1\n";
end
end
class MyRubyClass2 < Java::tabaqui.MyJavaClass
def myMethod
puts "Ruby method from MyRubyClass2\n";
end
end
a = MyRubyClass1.new
a.my_method #output: "Ruby method from MyRubyClass1"
a.invoke_my_method #output: "Java method"
b = MyRubyClass2.new
b.my_method #output: "Java method"
b.invoke_my_method #output: "Ruby method from MyRubyClass2"
The only solution i've found to obtain the expected result (ruby methods invoked in every case) is giving the overridden method an alias after defining it in ruby:
alias_method :myMethod, :my_method
Am i doing something wrong?
while confusing at first sight, this is "expected" once you understand alias ...
MyJavaClass#myMethod will have a my_method alias setup by the JRuby runtime.
in MyRubyClass1 you redefined my_method (alias) thus seeing the expected output.
however you did not override myMethod -> the convention does not work backwards.
while in MyRubyClass2 you redefined myMethod so it ends up doing virtual Java dispatch from invokeMyMethod(), es expected.
while this might seem confusing its how it is, the Java alias conventions are really there for "bare" consumers. while if you're extending a Java class you should stick to proper Java names. there's room for improvement here to re-define Java aliases once a proxy class is generated, although it might be a breaking change.

Package-private scope in Scala visible from Java

I just found out about a pretty weird behaviour of Scala scoping when bytecode generated from Scala code is used from Java code. Consider the following snippet using Spark (Spark 1.4, Hadoop 2.6):
import java.util.Arrays;
import java.util.List;
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.broadcast.Broadcast;
public class Test {
public static void main(String[] args) {
JavaSparkContext sc =
new JavaSparkContext(new SparkConf()
.setMaster("local[*]")
.setAppName("test"));
Broadcast<List<Integer>> broadcast = sc.broadcast(Arrays.asList(1, 2, 3));
broadcast.destroy(true);
// fails with java.io.IOException: org.apache.spark.SparkException:
// Attempted to use Broadcast(0) after it was destroyed
sc.parallelize(Arrays.asList("task1", "task2"), 2)
.foreach(x -> System.out.println(broadcast.getValue()));
}
}
This code fails, which is expected as I voluntarily destroy a Broadcast before using it, but the thing is that in my mental model it should not even compile, let alone running fine.
Indeed, Broadcast.destroy(Boolean) is declared as private[spark] so it should not be visible from my code. I'll try looking at the bytecode of Broadcast but it's not my specialty, that's why I prefer posting this question. Also, sorry I was too lazy to create an example that does not depend on Spark, but at least you get the idea. Note that I can use various package-private methods of Spark, it's not just about Broadcast.
Any idea of what's going on ?
If we reconstruct this issue with a simpler example:
package yuvie
class X {
private[yuvie] def destory(d: Boolean) = true
}
And decompile this in Java:
[yuvali#localhost yuvie]$ javap -p X.class
Compiled from "X.scala"
public class yuvie.X {
public boolean destory(boolean);
public yuvie.X();
}
We see that private[package] in Scala becomes public in Java. Why? This comes from the fact that Java private package isn't equivalent to Scala private package. There is a nice explanation in this post:
The important distinction is that 'private [mypackage]' in Scala is
not Java package-private, however much it looks like it. Scala
packages are truly hierarchical, and 'private [mypackage]' grants
access to classes and objects up to "mypackage" (including all the
hierarchical packages that may be between). (I don't have the Scala
spec reference for this and my understating here may be hazy, I'm
using [4] as a reference.) Java's packages are not hierarchical, and
package-private grants access only to classes in that package, as well
as subclasses of the original class, something that Scala's 'private
[mypackage]' does not allow.
So, 'package [mypackage]' is both more and less restrictive that Java
package-private. For both reasons, JVM package-private can't be used
to implement it, and the only option that allows the uses that Scala
exposes in the compiler is 'public.'

How to read lambda expression bytecode using ASM

How can I read the bytecode instructions from the body of a lambda expression using ASM?
EDIT 01-08-2016: I added another method using the SerializedLambda class which does not required a 3-rd party software (i.e., ByteBuddy), you can read about it in the section titled: "Using SerializedLambda" bellow.
Original Answer: Problem Explanation + Solving it Using ByteBuddy
The accepted answer did not contain concrete information about how to actually read the lambda byte code at run-time via asm (i.e., without javap) - so I thought I would add this information here for future reference and the benefit of others.
assume the following code:
public static void main(String[] args) {
Supplier<Integer> s = () -> 1;
byte[] bytecode = getByteCodeOf(s.getClass()); //this is the method that we need to create.
ClassReader reader = new ClassReader(bytecode);
print(reader);
}
I am assuming that you already have the print(ClassReader) code - if not see the answers to this question.
In order to read the byte-code via asm you first need to give asm (via the ClassReader) the actual byte-code of the lambda - the problem is that the lambda class is generated at runtime via the LambdaMetaFactory class and therefore the normal method of getting the byte code does NOT work:
byte[] getByteCodeOf(Class<?> c){
//in the following - c.getResourceAsStream will return null..
try (InputStream input = c.getResourceAsStream('/' + c.getName().replace('.', '/')+ ".class")){
byte[] result = new byte[input.available()];
input.read(result);
return result;
}
}
If we look on the name of the class c via c.getName() we will see something like defining.class.package.DefiningClass$$Lambda$x/y where x and y are numbers, now we can understand why the above does not work - there is no such resource on the classpath..
Although the JVM obviously knows the bytecode of the class, sadly, it has no ready-made API that allows you to retrieve it, on the other-hand, the JVM has an instrumentation API (via Agents) which allows you to write a class that can inspect the bytecode of a loading (and re-loading) classes.
We could have written such agent, and somehow communicate to it that we want to receive the bytecode of the lambda class - the agent may then request the JVM to reload that class (without changing it) - which will result in the agent receiving the byte-code of the reloading class and returning it back to us.
Luckily for us there is a library called ByteBuddy that have such agent already created, using this library - the following will work (if you are a maven user include dependencies for both byte-buddy-dep and byte-buddy-agent in your pom, also - see notes bellow about limitations).
private static final Instrumentation instrumentation = ByteBuddyAgent.install();
byte[] getByteCodeOf(Class<?> c) throws IOException {
ClassFileLocator locator = ClassFileLocator.AgentBased.of(instrumentation, c);
TypeDescription.ForLoadedType desc = new TypeDescription.ForLoadedType(c);
ClassFileLocator.Resolution resolution = locator.locate(desc.getName());
return resolution.resolve();
}
Limitation:
- Depending on your jvm installation you may have to install the agent via command line (see ByteBuddyAgent documentation and Instrumentation documentation)
New Answer: Using SerializedLambda
If the lambda you are trying to read implements an interface that extends Serializable - the LambdaMetafactory class actually generates a private methods called writeReplace which provides an instance of the class SerializedLambda. This instance can be used to retrieve the actual static method that was generated using the LambdaMetafactory.
So, for example here are 2 ways to have a "Serializable Lambda":
public class Sample {
interface SerializableRunnable extends Runnable, Serializable{}
public static void main(String... args) {
SerializableRunnable oneWay = () -> System.out.println("I am a serializable lambda");
Runnable anotherWay = (Serializable & Runnable) () -> System.out.println("I am a serializable lambda too!");
}
}
In the above examples both oneWay and anotherWay will have a generated writeReplace method which can be retrieved using reflection in the following way:
SerializedLambda getSerializedLambda(Serializable lambda) throws Exception {
final Method method = lambda.getClass().getDeclaredMethod("writeReplace");
method.setAccessible(true);
return (SerializedLambda) method.invoke(lambda);
}
If we look at the javadoc of SerializedLambda we will find the following methods:
public String getImplClass():
Get the name of the class containing the implementation method.
Returns:
the name of the class containing the implementation method
public String getImplMethodName():
Get the name of the implementation method.
Returns:
the name of the implementation method
Which means that you can now use ASM to read the class containing the lambda, get to the method that implement the lambda and modify/read it.
You can even get a reflective version of the lambda using this code:
Method getReflectedMethod(Serializable lambda) throws Exception {
SerializedLambda s = getSerializedLambda(lambda);
Class containingClass = Class.forName(s.getImplClass());
String methodName = s.getImplMethodName();
for (Method m : containingClass.getDeclaredMethods()) {
if (m.getName().equals(methodName)) return m;
}
throw new NoSuchElementException("reflected method could not be found");
}
A lambda compiles to a static method with a synthetic name. So to read the code using ASM, you would reverse engineer the method name ... then read it like any other method.
But if you just want to look at the bytecode for the lambda, it is simpler to use javap.

MWE2 Workflow component with Scala language

I'm trying to write a MWE2 workflow component using scala language.
Below is the scala code:
package com.ford.modelling.workflow
import org.eclipse.emf.mwe2.runtime.workflow.{IWorkflowComponent, IWorkflowContext}
class SayHello extends IWorkflowComponent {
var message : String = null;
def preInvoke {}
def invoke(ctx : IWorkflowContext) { System.out.println(message) }
def postInvoke {}
}
and below is the workflow code:
module com.ford.modelling.workflow.SomeWorklow
SayHello {}
I can't figure out why does this workflow complain for error:
'com.ford.modelling.workflow.SayHello' does not have a public default constructor.
I'd assume that the scala IDE plugin does not mimic the java protocol completely, e.g. the IType does not expose a no-args constructor. You may want to ask the scale folks about it.
The error message should vanish as soon as you add a default constructor explicitly. Does that make sense?
A quick google search indicated that there probably no syntax for a default constructor so I'd assume it's a scala tooling problem. Does the problem occur at runtime, too?

Java or any other language: Which method/class invoked mine?

I would like to write a code internal to my method that print which method/class has invoked it.
(My assumption is that I can't change anything but my method..)
How about other programming languages?
EDIT: Thanks guys, how about JavaScript? python? C++?
This is specific to Java.
You can use Thread.currentThread().getStackTrace(). This will return an array of StackTraceElements.
The 2nd element in the array will be the calling method.
Example:
public void methodThatPrintsCaller() {
StackTraceElement elem = Thread.currentThread.getStackTrace()[2];
System.out.println(elem);
// rest of you code
}
If all you want to do is print out the stack trace and go hunting for the class, use
Thread.dumpStack();
See the API doc.
Justin has the general case down; I wanted to mention two special cases demonstrated by this snippit:
import java.util.Comparator;
public class WhoCalledMe {
public static void main(String[] args) {
((Comparator)(new SomeReifiedGeneric())).compare(null, null);
new WhoCalledMe().new SomeInnerClass().someInnerMethod();
}
public static StackTraceElement getCaller() {
//since it's a library function we use 3 instead of 2 to ignore ourself
return Thread.currentThread().getStackTrace()[3];
}
private void somePrivateMethod() {
System.out.println("somePrivateMethod() called by: " + WhoCalledMe.getCaller());
}
private class SomeInnerClass {
public void someInnerMethod() {
somePrivateMethod();
}
}
}
class SomeReifiedGeneric implements Comparator<SomeReifiedGeneric> {
public int compare(SomeReifiedGeneric o1, SomeReifiedGeneric o2) {
System.out.println("SomeRefiedGeneric.compare() called by: " + WhoCalledMe.getCaller());
return 0;
}
}
This prints:
SomeRefiedGeneric.compare() called by: SomeReifiedGeneric.compare(WhoCalledMe.java:1)
somePrivateMethod() called by: WhoCalledMe.access$0(WhoCalledMe.java:14)
Even though the first is called "directly" from main() and the second from SomeInnerClass.someInnerMethod(). These are two cases where there is a transparent call made in between the two methods.
In the first case, this is because we are calling the bridge method to a generic method, added by the compiler to ensure SomeReifiedGeneric can be used as a raw type.
In the second case, it is because we are calling a private member of WhoCalledMe from an inner class. To accomplish this, the compiler adds a synthetic method as a go-between to override the visibility problems.
the sequence of method calls is located in stack. this is how you get the stack: Get current stack trace in Java then get previous item.
Since you asked about other languages, Tcl gives you a command (info level) that lets you examine the call stack. For example, [info level -1] returns the caller of the current procedure, as well as the arguments used to call the current procedure.
In Python you use the inspect module.
Getting the function's name and file name is easy, as you see in the example below.
Getting the function itself is more work. I think you could use the __import__ function to import the caller's module. However you must somehow convert the filename to a valid module name.
import inspect
def find_caller():
caller_frame = inspect.currentframe().f_back
print "Called by function:", caller_frame.f_code.co_name
print "In file :", caller_frame.f_code.co_filename
#Alternative, probably more portable way
#print inspect.getframeinfo(caller_frame)
def foo():
find_caller()
foo()
Yes, it is possible.
Have a look at Thread.getStackTrace()
In Python, you should use the traceback or inspect modules. These will modules will shield you from the implementation details of the interpreter, which can differ even today (e.g. IronPython, Jython) and may change even more in the future. The way these modules do it under the standard Python interpreter today, however, is with sys._getframe(). In particular, sys._getframe(1).f_code.co_name provides the information you want.

Categories