How do I disambiguate in Scala between methods with vararg and without - java

I'm trying to use the java jcommander library from Scala. The java JCommander class has multiple constructors:
public JCommander(Object object)
public JCommander(Object object, ResourceBundle bundle, String... args)
public JCommander(Object object, String... args)
I want to to call the first constructor that takes no varargs. I tried:
jCommander = new JCommander(cmdLineArgs)
I get the error:
error: ambiguous reference to overloaded definition,
both constructor JCommander in class JCommander of type (x$1: Any,x$2: <repeated...>[java.lang.String])com.beust.jcommander.JCommander
and constructor JCommander in class JCommander of type (x$1: Any)com.beust.jcommander.JCommander
match argument types (com.lasic.CommandLineArgs) and expected result type com.beust.jcommander.JCommander
jCommander = new JCommander(cmdLineArgs)
I've also tried using a named parameter, but got the same result:
jCommander = new JCommander(`object` = cmdLineArgs)
How do I tell Scala I want to call the constructor that doesn't take varargs?
I'm using Scala 2.8.0.

Sorry, I now realize this is a known interoperability problem with Java. See this question and the ticket. The only work around I know of is to create a small Java class just to disambiguate these calls.

The only Scala solution to this problem that I know involves reflection.
Ambiguous Methods
Let's suppose we have a Java test class:
public class Ambig {
public Ambig() {}
public String say(Object o) { return o.toString(); }
public String say(Object o, String... ss) { return o.toString()+ss.length; }
}
We can get access to the method via reflection directly:
val ambig = new Ambig
val methods = ambig.getClass.getMethods.filter(_.getName == "say")
val wanted = methods.find(_.getParameterTypes.length == 1).get
wanted.invoke(ambig, Some(5)).asInstanceOf[String]
or we can use structural types (which use reflection under the hood) to achieve the same thing with less boilerplate:
def sayer(speaker: { def say(o: Object): String }, o: Object) = speaker.say(o)
sayer(new Ambig, Some(5))
Ambiguous Constructors
Our strategy has to differ because we don't actually have an object to begin with. Let's suppose we have the Java class
public class Ambig2 {
public final String say;
public Ambig2(Object o) { say = o.toString(); }
public Ambig2(Object o, String... ss) { say = o.toString()+ss.length; }
}
The structural types approach no longer works, but we can still use reflection:
val mkAmbig2 = classOf[Ambig2].getConstructors.filter(_.getParameterTypes.length==1)
val ambig = mkAmbig2.head.newInstance(Some(5)).asInstanceOf[Ambig2]
ambig.say // Some(5)

I think your easiest option is to have a Java class with a factory method to bridge the issue:
package com.beust.jcommander;
public class JCommanderFactory {
public static createWithArgs(Object cmdLineArgs) {
return new JCommander(cmdLineArgs);
}
}
Alternatively you could use http://jewelcli.sourceforge.net/usage.html instead. JewelCli has an unambiguous factory method for the same purpose and also uses PICA (Proxied Interfaces Configured with Annotations) technique http://www.devx.com/Java/Article/42492/1954.
In fact I have an example of using JewelCLI with Scala here on Stack Overflow.

The way to avoid this ambiguity is to force the compiler to pick the overload that takes more than one argument, using Scala's collection explosion syntax to pass in a singleton collection:
import java.util.stream.Stream
val stream = Stream.of(List(1):_*)

You can call the constructor with varags, but pass an empty list of varags.
(Of course, if you know that constructing JCommander with empty varags will produce the same result as calling the overloaded constructor (or method) without vargs)
jCommander = new JCommander(cmdLineArgs, Nil: _*)

Related

Sun Codemodel generic method invocation

I'm using Codemodel library for java-class generation. Is there a way to generate a generic method invocation which looks like this:
clazz.<String>get(value)
There is certainly a way of just casting a return result to a correct type using the following expression:
JExpr.cast(stringType, clazz.invoke("get").arg(value))
which results in
(String) clazz.get(value)
but the preferred way of casting is the first one, as this code is generating templates for further manual editing by developers.
With the existing JCodeModel API, there is no pre-built way to handle this. You can, however, define your own JStatement type to generate the generic declaration like this:
JDefinedClass definedClass = codeModel._class(JMod.PUBLIC, "org.test.Tester", ClassType.CLASS);
JMethod method = definedClass.method(JMod.PUBLIC, codeModel.VOID, "test");
final JType targetType = codeModel.ref(String.class);
final JVar clazzVar = method.body().decl(codeModel.ref(Class.class), "clazz", JExpr.invoke("getClass"));
method.body().add(new JStatement(){
#Override
public void state(JFormatter f) {
f.g(clazzVar).p(".<").g(targetType).p(">").p("get").p("();").nl();
}
});
Which generates:
package org.test;
public class Tester {
public void test() {
Class clazz = getClass();
clazz.<String >get();
}
}
This is by no mean a complete solution (It's missing method call arguments for instance). Take a look at the implementation of the generate() method in JInvocation for the details that are required.

Implicit wrap of Java Null

I need to access a large set of Java interfaces from Scala. These interfaces have methods that might return Null, and I want to convert them to Option[T]
I found other answers that describe Option.apply() like these
How to implicitly wrap a value that can be null or an array into an Scala Option
Option-izing Java getters
However, this requires that for each Java interface, I manually create a Scala wrapper. Like this...
class ScalaFoo extends JavaFoo {
def bar = Option(super.bar)
}
That seems messy, hard to maintain, and prone to error. I don't want all that extra code that does nothing, and I want to automatically wrap all my Java interfaces, so that if one changes, the wrapper also changes.
Surely, there is a way to do this with implicits, isn't there?
I recently ended up with something like this:
object Implicits {
implicit class ConvertToOption[T](t: T) {
def optional = Option(t)
}
}
Usage:
Suppose you have a following Java interface:
public interface Fooable {
public String getFoo();
}
public class Foo implements Fooable {
public String getFoo() {
return null;
}
}
In your Scala code:
import Implicits._
val foo = new Foo()
val myOptionalValue = foo.getFoo.optional //returns an Option[String], in this case None because getFoo returns null
I'm not aware of a great way to do this either. However I saw a nice approach on twitter recently:
import Option.{apply => ?}
val fooBar = ?(javaFoo.bar)

Java - Factory Method that returns generic Base type

I'm trying to genericize a factory method that returns
a generic Base class. It works, but I'm getting the
"BaseClass is a raw type..." warning.
I've read through the Java docs on Generic methods,
but I'm still not quite getting how to accomplish this.
Here's some code:
Class #1
//base abstract class
public abstract class BaseFormatter<T>
{
public abstract String formatValue(T value);
}
Class #2
//two implementations of concrete classes
public class FooFormatter extends BaseFormatter<Integer>
{
#Override
public String formatValue(Integer value)
{
//return a formatted String
}
}
Class #3
public class BarFormatter extends BaseFormatter<String>
{
#Override
public String formatValue(String value)
{
//return a formatted String
}
}
Factory Method in a separate class
public static BaseFormatter getFormatter(Integer unrelatedInteger)
{
if (FOO_FORMATTER.equals(unrelatedInteger))
return new FooFormatter();
else if (BAR_FORMATTER.equals(unrelatedInteger))
return new BarFormatter();
//else...
}
Call to the Factory Method from elsewhere in the code
BaseFormatter<Integer> formatter = getFormatter(someInteger);
formatter.formatValue(myIntegerToFormat);
The problem is the getFormatter() method warns that BaseFormatter is
a raw type, which it is. I've tried various things like BaseFormatter
et al. I, of course, want the return type to be generic, as in the declared
BaseFormatter in the calling method.
Note that the formatter type is not based on class type. e.g. not all Integer
values are formatted with a FooFormatter. There are two or three different
ways an Integer (or String, or List) can be formatted. That's what the
param unrelatedInteger is for.
Thanks in advance for any feedback.
If getFormatter is defined in BaseFormatter, then use:
public static BaseFormatter<T> getFormatter(Integer unrelatedInteger)
If getFormatter is defined in another class than BaseFormatter, then use:
public static BaseFormatter<?> getFormatter(Integer unrelatedInteger)
You're actuaaly saying that there's no connection between the typed parameter of BaseFormatter and the unrelatedInteger that is passed as argument to the getFormatter method.
I get some other warning:
Uncehcked Assignment: BaseFormatter to BaseFormatter<Integer>
This warning is worse than the one you indicated. It warns that this user code might try to insert a BaseFormatter<String> into BaseFormatter<Integer>, something that will be noticed only when fails in runtime... Consider a user accidentally uses you factory method like such:
BaseFormatter<Integer> myUnsafeFormatter =
FormatterFactory.getFormatter(unrelatedIntegerForBarFormatter);
The compiler cannot relate the unrelatedInteger with the parameterized type of the returned BaseFormatter.
Alternitavely, I'd let the user explicitly use the concrete formatter constructors. Any common code shared by all formatters could be put into FormatterUtils class (just don't let that utils class to grow to much...).
Some type systems in academic languages can express a so-called dependent sum. Java certainly cannot; so what, sensibly, could be the type of the object returned by the getFormatter method? The best we can do is BaseFormatter< ? extends Object >, or BaseFormatter< ? > for short, as Integer and String have only Object in common.
I think the original post begs the question, why must we use an integer to decide what formatter to return, and if the type of formatter would not be known by the caller, why would the caller need a stronger variable type than BaseFormatter< ? >?

How to get string name of a method in java?

How can I find out through reflection what is the string name of the method?
For example given:
class Car{
public void getFoo(){
}
}
I want to get the string "getFoo", something like the following:
Car.getFoo.toString() == "getFoo" // TRUE
You can get the String like this:
Car.class.getDeclaredMethods()[0].getName();
This is for the case of a single method in your class. If you want to iterate through all the declared methods, you'll have to iterate through the array returned by Car.class.getDeclaredMethods():
for (Method method : Car.class.getDeclaredMethods()) {
String name = method.getName();
}
You should use getDeclaredMethods() if you want to view all of them, getMethods() will return only public methods.
And finally, if you want to see the name of the method, which is executing at the moment, you should use this code:
Thread.currentThread().getStackTrace()[1].getMethodName();
This will get a stack trace for the current thread and return the name of the method on its top.
Since methods aren't objects themselves, they don't have direct properties (like you would expect with first-class functions in languages like JavaScript).
The closest you can do is call Car.class.getMethods()
Car.class is a Class object which you can use to invoke any of the reflection methods.
However, as far as I know, a method is not able to identify itself.
So, you want to get the name of the currently executing method? Here's a somewhat ugly way to do that:
Exception e = new Exception();
e.fillInStackTrace();
String methodName = e.getStackTrace()[0].getMethodName();
Look into this thread:
Getting the name of the currently executing method
It offers some more solutions - for example:
String name = new Object(){}.getClass().getEnclosingMethod().getName();
With Java 8, you can do this with a few lines of code (almost) without any additional libraries. The key is to convert your method into a serialisable lambda expression. Therefore, you can just define a simple interface like this:
#FunctionalInterface
public interface SerializableFunction<I, O> extends Function<I, O>, Serializable {
// Combined interface for Function and Serializable
}
Now, we need to convert our lambda expression into a SerializedLambda object. Apparently, Oracle does not really want us to do that, so take this with a grain of salt... As the required method is private, we need to invoke it using reflections:
private static final <T> String nameOf(SerializableFunction<T, ?> lambda) {
Method findMethod = ReflectionUtils.findMethod(lambda.getClass(), "writeReplace");
findMethod.setAccessible(true);
SerializedLambda invokeMethod = (SerializedLambda) ReflectionUtils.invokeMethod(findMethod, lambda);
return invokeMethod.getImplMethodName();
}
I'm using Springs ReflectionUtils class here for simplicity, but you can of course replace this by manually looping through all superclasses and use getDeclaredMethod to find the writeReplace method.
And this is it already, now you can use it like this:
#Test
public void testNameOf() throws Throwable {
assertEquals("getName", nameOf(MyClassTest::getName));
}
I haven't checked this with Java 9s module system, so as a little disclaimer it might be more tricky to do this with more recent Java versions...
try this,
import java.lang.reflect.*;
public class DumpMethods {
public static void main(String args[]) {
try {
Class c = Class.forName(args[0]);
Method m[] = c.getDeclaredMethods();
for (int i = 0; i < m.length; i++)
System.out.println(m[i].toString());
} catch (Throwable e) {
System.err.println(e);
}
}
}
Wait, since you already know the method name, can't you just type it as a string?
Instead of (pseudo) Class.methodName.toString(), just use "methodName".
Otherwise you can use Class#getDeclaredMethods() to get all the methods in a class

Type-safe method reflection in Java

Is any practical way to reference a method on a class in a type-safe manner? A basic example is if I wanted to create something like the following utility function:
public Result validateField(Object data, String fieldName,
ValidationOptions options) { ... }
In order to call it, I would have to do:
validateField(data, "phoneNumber", options);
Which forces me to either use a magic string, or declare a constant somewhere with that string.
I'm pretty sure there's no way to get around that with the stock Java language, but is there some kind of (production grade) pre-compiler or alternative compiler that may offer a work around? (similar to how AspectJ extends the Java language) It would be nice to do something like the following instead:
public Result validateField(Object data, Method method,
ValidationOptions options) { ... }
And call it with:
validateField(data, Person.phoneNumber.getter, options);
As others mention, there is no real way to do this... and I've not seen a precompiler that supports it. The syntax would be interesting, to say the least. Even in your example, it could only cover a small subset of the potential reflective possibilities that a user might want to do since it won't handle non-standard accessors or methods that take arguments, etc..
Even if it's impossible to check at compile time, if you want bad code to fail as soon as possible then one approach is to resolve referenced Method objects at class initialization time.
Imagine you have a utility method for looking up Method objects that maybe throws error or runtime exception:
public static Method lookupMethod( Class c, String name, Class... args ) {
// do the lookup or throw an unchecked exception of some kind with a really
// good error message
}
Then in your classes, have constants to preresolve the methods you will use:
public class MyClass {
private static final Method GET_PHONE_NUM = MyUtils.lookupMethod( PhoneNumber.class, "getPhoneNumber" );
....
public void someMethod() {
validateField(data, GET_PHONE_NUM, options);
}
}
At least then it will fail as soon as MyClass is loaded the first time.
I use reflection a lot, especially bean property reflection and I've just gotten used to late exceptions at runtime. But that style of bean code tends to error late for all kinds of other reasons, being very dynamic and all. For something in between, the above would help.
There isn't anything in the language yet - but part of the closures proposal for Java 7 includes method literals, I believe.
I don't have any suggestions beyond that, I'm afraid.
Check out https://proxetta.jodd.org/refs/methref. It uses the Jodd proxy library (Proxetta) to proxy your type. Not sure about its performance characteristics, but it does provide type safety.
An example: Suppose Str.class has method .boo(), and you want to get its name as the string "boo":
String methodName = Methref.of(Str.class).name(Str::boo);
There's more to the API than the example above: https://oblac.github.io/jodd-site/javadoc/jodd/methref/Methref.html
Is any practical way to reference a method on a class in a type-safe manner?
First of all, reflection is type-safe. It is just that it is dynamically typed, not statically typed.
So, assuming that you want a statically typed equivalent of reflection, the theoretical answer is that it is impossible. Consider this:
Method m;
if (arbitraryFunction(obj)) {
m = obj.getClass().getDeclaredMethod("foo", ...);
} else {
m = obj.getClass().getDeclaredMethod("bar", ...);
}
Can we do this so that that runtime type exceptions cannot happen? In general NO, since this would entail proving that arbitraryFunction(obj) terminates. (This is equivalent to the Halting Problem, which is proven to be unsolvable in general, and is intractable using state-of-the-art theorem proving technology ... AFAIK.)
And I think that this road-block would apply to any approach where you could inject arbitrary Java code into the logic that is used to reflectively select a method from an object's class.
To my mind, the only moderately practical approach at the moment would be to replace the reflective code with something that generates and compiles Java source code. If this process occurs before you "run" the application, you've satisfied the requirement for static type-safety.
I was more asking about reflection in which the result is always the same. I.E. Person.class.getMethod("getPhoneNumber", null) would always return the same method and it's entirely possible to resolve it at compile time.
What happens if after compiling the class containing this code, you change Person to remove the getPhoneNumber method?
The only way you can be sure that you can resolve getPhoneNumber reflectively is if you can somehow prevent Person from being changed. But you can't do that in Java. Runtime binding of classes is a fundamental part of the language.
(For record, if you did that for a method that you called non-reflectively, you would get an IncompatibleClassChangeError of some kind when the two classes were loaded ...)
It has been pointed out that in Java 8 and later you could declare your validator something like this:
public Result validateField(Object data,
SomeFunctionalInterface function,
ValidationOptions options) { ... }
where SomeFunctionalInterface corresponds to the (loosely speaking) common signature of the methods you are validating.
Then you can call it with a method reference; e.g.
validateField(data, SomeClass::someMethod, options)
This is approach is statically type-safe. You will get a compilation error if SomeClass doesn't have someMethod or if it doesn't conform to SomeFunctionalInterface.
But you can't use a string to denote the method name. Looking up a method by name would entail either reflection ... or something else that side-steps static (i.e. compile time / load time) type safety.
Java misses the syntax sugar to do something as nice as Person.phoneNumber.getter. But if Person is an interface, you could record the getter method using a dynamic proxy. You could record methods on non-final classes as well using CGLib, the same way Mockito does it.
MethodSelector<Person> selector = new MethodSelector<Person>(Person.class);
selector.select().getPhoneNumber();
validateField(data, selector.getMethod(), options);
Code for MethodSelector: https://gist.github.com/stijnvanbael/5965609
Inspired by mocking frameworks, we could dream up the following syntax:
validator.validateField(data, options).getPhoneNumber();
Result validationResult = validator.getResult();
The trick is the generic declaration:
class Validator {
public <T> T validateField(T data, options) {...}
}
Now the return type of the method is the same as your data object's type and you can use code completion (and static checking) to access all the methods, including the getter methods.
As a downside, the code isn't quite intuitive to read, since the call to the getter doesn't actually get anything, but instead instructs the validator to validate the field.
Another possible option would be to annotate the fields in your data class:
class FooData {
#Validate(new ValidationOptions(...))
private PhoneNumber phoneNumber;
}
And then just call:
FooData data;
validator.validate(data);
to validate all fields according to the annotated options.
The framework picklock lets you do the following:
class Data {
private PhoneNumber phoneNumber;
}
interface OpenData {
PhoneNumber getPhoneNumber(); //is mapped to the field phoneNumber
}
Object data = new Data();
PhoneNumber number = ObjectAccess
.unlock(data)
.features(OpenData.class)
.getPhoneNumber();
This works in a similar way setters and private methods. Of course, this is only a wrapper for reflection, but the exception does not occur at unlocking time not at call time. If you need it at build time, you could write a unit test with:
assertThat(Data.class, providesFeaturesOf(OpenData.class));
I found a way to get the Method instance using Lambdas. It works only on interface methods though currently.
It works using net.jodah:typetools which is a very lightweight library.
https://github.com/jhalterman/typetools
public final class MethodResolver {
private interface Invocable<I> {
void invokeWithParams(I instance, Class<?>[] parameterTypes) throws Throwable;
}
interface ZeroParameters<I, R> extends Invocable<I> {
R invoke(I instance) throws Throwable;
#Override
default void invokeWithParams(I instance, Class<?>[] parameterTypes) throws Throwable {
invoke(instance);
}
}
public static <I, R> Method toMethod0(ZeroParameters<I, R> call) {
return toMethod(ZeroParameters.class, call, 1);
}
interface OneParameters<I, P1, R> extends Invocable<I> {
R invoke(I instance, P1 p1) throws Throwable;
#Override
default void invokeWithParams(I instance, Class<?>[] parameterTypes) throws Throwable {
invoke(instance, param(parameterTypes[1]));
}
}
public static <I, P1, R> Method toMethod1(OneParameters<I, P1, R> call) {
return toMethod(OneParameters.class, call, 2);
}
interface TwoParameters<I, P1, P2, R> extends Invocable<I> {
R invoke(I instance, P1 p1, P2 p2) throws Throwable;
#Override
default void invokeWithParams(I instance, Class<?>[] parameterTypes) throws Throwable {
invoke(instance, param(parameterTypes[1]), param(parameterTypes[2]));
}
}
public static <I, P1, P2, R> Method toMethod2(TwoParameters<I, P1, P2, R> call) {
return toMethod(TwoParameters.class, call, 3);
}
private static final Map<Class<?>, Object> parameterMap = new HashMap<>();
static {
parameterMap.put(Boolean.class, false);
parameterMap.put(Byte.class, (byte) 0);
parameterMap.put(Short.class, (short) 0);
parameterMap.put(Integer.class, 0);
parameterMap.put(Long.class, (long) 0);
parameterMap.put(Float.class, (float) 0);
parameterMap.put(Double.class, (double) 0);
}
#SuppressWarnings("unchecked")
private static <T> T param(Class<?> type) {
return (T) parameterMap.get(type);
}
private static <I> Method toMethod(Class<?> callType, Invocable<I> call, int responseTypeIndex) {
Class<?>[] typeData = TypeResolver.resolveRawArguments(callType, call.getClass());
Class<?> instanceClass = typeData[0];
Class<?> responseType = responseTypeIndex != -1 ? typeData[responseTypeIndex] : Void.class;
AtomicReference<Method> ref = new AtomicReference<>();
I instance = createProxy(instanceClass, responseType, ref);
try {
call.invokeWithParams(instance, typeData);
} catch (final Throwable e) {
throw new IllegalStateException("Failed to call no-op proxy", e);
}
return ref.get();
}
#SuppressWarnings("unchecked")
private static <I> I createProxy(Class<?> instanceClass, Class<?> responseType,
AtomicReference<Method> ref) {
return (I) Proxy.newProxyInstance(MethodResolver.class.getClassLoader(),
new Class[] {instanceClass},
(proxy, method, args) -> {
ref.set(method);
return parameterMap.get(responseType);
});
}
}
Usage:
Method method = MethodResolver.toMethod2(SomeIFace::foobar);
System.out.println(method); // public abstract example.Result example.SomeIFace.foobar(java.lang.String,boolean)
Method get = MethodResolver.<Supplier, Object>toMethod0(Supplier::get);
System.out.println(get); // public abstract java.lang.Object java.util.function.Supplier.get()
Method accept = MethodResolver.<IntFunction, Integer, Object>toMethod1(IntFunction::apply);
System.out.println(accept); // public abstract java.lang.Object java.util.function.IntFunction.apply(int)
Method apply = MethodResolver.<BiFunction, Object, Object, Object>toMethod2(BiFunction::apply);
System.out.println(apply); // public abstract java.lang.Object java.util.function.BiFunction.apply(java.lang.Object,java.lang.Object)
Unfortunately you have to create a new interface and method based on the parameter count and whether the method returns void or not.
However, if you have a somewhat fixed/limited method signature/parameter types, then this becomes quite handy.

Categories