Skip to content
New issue

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

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

Already on GitHub? # to your account

Eclipse Compiler vs Javac #81

Closed
numeralnathan opened this issue Mar 10, 2016 · 5 comments
Closed

Eclipse Compiler vs Javac #81

numeralnathan opened this issue Mar 10, 2016 · 5 comments

Comments

@numeralnathan
Copy link

The following code compiles just find with the Eclipse IDE compiler. However, javac can't compile it.

StreamEx.
   iterate(clazz, cls -> (Class) cls.getSuperclass()).
   takeWhile(Objects::nonNull).
   map(Class::getDeclaredFields);

Here is the error message from javac.

<R>map(java.util.function.Function<? super T,? extends R>) in one.util.streamex.AbstractStreamEx is defined in an inaccessible class or interface

It seems that javac isn't able to resolve the generic return type of takeWhile().

@numeralnathan
Copy link
Author

Here is the workaround.

StreamEx<Class<?>> classStream;

classStream = StreamEx.
   iterate(clazz, cls -> cls.getSuperclass());

classStream = classStream.
   takeWhile(Objects::nonNull);

classStream.
   map(Class::getDeclaredFields);

@numeralnathan
Copy link
Author

I don't know if javac is too strict or if Eclipse IDE compiler is too loose on the implementation. Either way a bug should be filed against javac or Eclipse IDE compiler. If javac is correct in the implementation, then the StreamEx library definitely should be adjusted. If javac is incorrect, then please consider changing the StreamEx library.

@amaembo
Copy link
Owner

amaembo commented Mar 11, 2016

Note that you are using the raw type Class. Using raw types is almost always bad idea. In any case it does not worth fixing the compilation of code involving raw types. Try these variations:

StreamEx.
   iterate(clazz, (Class<?> cls) -> cls.getSuperclass()).
   takeWhile(Objects::nonNull).
   map(Class::getDeclaredFields);

Or

StreamEx.<Class<?>>
   iterate(clazz, cls -> cls.getSuperclass()).
   takeWhile(Objects::nonNull).
   map(Class::getDeclaredFields);

Both versions are compiled fine for me.

Also it should be noted that I see two error messages reported by javac, and the second one is more interesting:

test.java:8: error: <R>map(Function<? super T,? extends R>) in AbstractStreamEx is defined in an inaccessible class or interface
   takeWhile(Objects::nonNull).
                              ^
  where R,T are type-variables:
    R extends Object declared in method <R>map(Function<? super T,? extends R>)
    T extends Object declared in class AbstractStreamEx
test.java:9: error: incompatible types: invalid method reference
   map(Class::getDeclaredFields);
       ^
    method getDeclaredFields in class Class<T> cannot be applied to given types
      required: no arguments
      found: Object
      reason: actual and formal argument lists differ in length
  where T is a type-variable:
    T extends Object declared in class Class

This actually means that the inferred type of the stream elements is Object. Which is quite expected: when you use raw type in at least one position, you may expect, that other types of the expression will be erased to the bounds as well.

I admit that the first message about inaccessible class is very confusing. I think it's actually a javac problem, but the problem is in the message only. You cannot expect that such code compiles.

@numeralnathan
Copy link
Author

The first case didn’t work. The second case worked! Using <Class<?>> always gets me.

I am using Java version…

java version "1.8.0_73"

Java(TM) SE Runtime Environment (build 1.8.0_73-b02)

Java HotSpot(TM) 64-Bit Server VM (build 25.73-b02, mixed mode)

-Nathan

From: Tagir Valeev [mailto:notifications@github.com]
Sent: Thursday, March 10, 2016 6:02 PM
To: amaembo/streamex streamex@noreply.github.com
Cc: Nathan Reynolds nathanila@gmail.com
Subject: Re: [streamex] Eclipse Compiler vs Javac (#81)

Note that you are using the raw type Class. Using raw types is almost always bad idea. In any case it does not worth fixing the compilation of code involving raw types. Try these variations:

StreamEx.
iterate(clazz, cls -> (Class<?>) cls.getSuperclass()).
takeWhile(Objects::nonNull).
map(Class::getDeclaredFields);

And (better)

StreamEx.<Class<?>>
iterate(clazz, cls -> cls.getSuperclass()).
takeWhile(Objects::nonNull).
map(Class::getDeclaredFields);

Also which javac version are you using?


Reply to this email directly or view it on GitHub #81 (comment) .

@amaembo
Copy link
Owner

amaembo commented Mar 11, 2016

I edited the message after posting it (fixing the first case). It seems that you've answered to the e-mail notification which shows the first version of the post. StreamEx.iterate(clazz, (Class<?> cls) -> cls.getSuperclass()). should work as well.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants