I have a scala object defined like the following:
package com.example
object Foo {
def bar(): String = "Interesting Result"
}
I know that I can call Foo$.MODULE$.bar()
from Java if Foo
is in the build and runtime classpath, but in my situation Foo
is not in the build classpath and may or may not be configured in the runtime classpath.
From my Java code I'd like to use reflection to call bar()
if it is available on the runtime classpath, otherwise I'll fall back to a default implementation.
Is it possible to do this?
You can do it with code that looks something like this:
package com.example.java;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Example {
/**
* Returns null or the result of calling a method on a scala object from java
*/
public String callScalaFromJava(){
String result = null;
try {
Class<?> clazz = Class.forName("com.example.Foo$"); // Note the trailing '$'
Method method = clazz.getDeclaredMethod("bar");
Field field = clazz.getField("MODULE$");
Object instance = field.get(null);
Object obj = method.invoke(instance, new Object[] {});
if (obj instanceof String) {
result = (String) obj);
}
} catch (Exception ex) {
// SWALLOWING
}
return result;
}
}
The object Foo class is com.example.Foo$
so if you can just load that class, everything will go fine without using reflection:
try {
Class.forName("com.example.Foo$");
String s = com.example.Foo$.MODULE$.bar();
// ...
} catch (Exception ex) {
String s = // fallback solution
// ...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With