Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot resolve method/constructor signatures when null is passed #90

Closed
slavchev opened this issue Jun 1, 2015 · 7 comments
Closed

Comments

@slavchev
Copy link

slavchev commented Jun 1, 2015

The following method cannot be resolved from JavaScript when called with null argument.

public class Class1 {
  void method1(Object o) { ... }
  void method1(String s) { ... }
}

Suggestion: provide null function, e.g. javanull. For example:

var c = new Class1();
c.method1(javanull(java.lang.Object)); // method1(Object o)
c.method1(javanull(java.lang.String)); // method1(Strnig s)

Another option is to attach null property to the class object. For example

var c = new Class1();
c.method1(java.lang.Object.null); // method1(Object o)
c.method1(java.lang.String.null); // method1(Strnig s)

Any other suggestions are welcome.

@slavchev slavchev added the bug label Jun 1, 2015
@Plamen5kov Plamen5kov self-assigned this Aug 7, 2015
@Plamen5kov
Copy link
Contributor

Possible problems while working with null parameter on the javascript side, having the set up described in the issue:
e.g:

1. var a = new SomeClass(); //returns Object
2.
3. if(a == null) {
4.    c.method1(a);
5. }
6.
7. 
8. var b  = new JavaNullClass();
9. 
10. if(b == null) {
11.     c.method1(b)
12. }

What might happen:
(case1)
Lets assume that on line 8. new JavaNullClass is some class(or method) that might return javascript "null"(this is the current implementation).
In this case on the JS side the user needs to take care about this scenario, and know that at runtime, method1 on line 11. might have unexpected behavior.

(case 2)
If the runtime returns some object that contains the information about it returning "null" there will be unexpected behavior in JS side of the code.
e.g.
line 3: in (case1) will return true
line 3: in (case2) will return false, because we wont return javascript "null", but an Object.

So in conclusion:
case1 -> unexpected behavior on the native side.
case2 -> unexpected behavior on the JS side

@slavchev
Copy link
Author

Suppose we have the following Java code

public class Util {
  public String getDataFileName() {
    ...
  }
}
public class SomeClass {
  public byte[] getData(String dataFileName) {
    ...
  }
  public byte[] getData(File dataFile) {
    ...
  }
  ...
}

and the following JavaScript code

var name = util.getDataFileName();
var data = someClass.getData(name);

Currently in the scenario when both getData methods accept null argument (e.g. provide some fallback mechanism) we will not to able to resolve the correct Java method as null is valid argument for both of them. Obviously name is of type String but we are not able to infer it.

I think we need both approaches suggested above or something else. Using java.lang.String.null is an option when we want to state explicitly which method we want to call. However this approach won't help in the scenario where getDataFileName() returns null. For this scenario we need additional information in order to infer the correct type. A possible option could be providing checkForNull function as follows

var name = util.getDataFileName();
var data = someClass.getData(checkForNull(java.lang.String, name));

However this option does not guide the developer when to use it. My guess is that the need for method resolution will be relatively small and this or similar approach will be well accepted. This approach doesn't exclude the possibility of subtle bugs though.

@petekanev
Copy link
Contributor

The syntax for passing null of a specific type is as has been suggested out by @slavchev

var c = new Class1();
c.method1(java.lang.Object.null); // method1(Object o)
c.method1(java.lang.String.null); // method1(Strnig s)

Regarding nulls returned from Java methods - developers will need to check for null and specify the type they wish to use in a follow up function like so.

var result = javaClass.methodThatReturnsSomeNull();
var myNull;
if(!result)
  myNull = com.a.Some.null;

@Plamen5kov Plamen5kov added this to the 2.0.0 milestone Apr 18, 2016
@petekanev
Copy link
Contributor

petekanev commented Apr 27, 2016

Please note that with the recent fix there is a breaking change. Consider the following scenario:

Updated:
In Java, you have a constructor which receives a java.lang.Object parameter. Up until this moment it was possible to pass a primitive value without explicitly wrapping it in a reference type object and it would resolve normally to Integer with value 42:
Java : public JavaClass(Object val) { // }
JavaScript: new com.a.JavaClass(42);

That is no longer supported, and if you wish to invoke the same constructor with a primitive, you will need to make sure that you create an object wrapper.
Javascript: new com.a.JavaClass(new java.lang.Integer(42));

@NathanaelA

This comment was marked as abuse.

@petekanev
Copy link
Contributor

@NathanaelA Java objects used to have their constructors resolved, and be instantiated in Java. Before creating an instance and after finding the most adequate constructor, we used to do argument conversion - matching each argument against what the constructor expected , very similar to the one we had in C++, but instead in Java.
We thought that it would only be right that constructor resolution and object creation were moved to the C++ code for consistency, as there already was code in place that took care of argument and method resolution; and it also happened to boost performance during object creation by a sliver.

The changes only affect object creation and should not require that you change the way method invocation has worked so far. I've updated my original comment to reflect on that.

@NathanaelA

This comment was marked as abuse.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants