Objectify generics compile time error with incompatible objects in Java 7 - java

In java 6 the following line compiles however in Java 7 I get an incompatible type error (See below). Any ideas what is going on here?
Player player = new FPlayer();
player.setId("SomeString");
player.setWId(123456, "SomeString");
Key<Player> keyForPlayer = ofy().save().entity(player).now();
Gets a compile time error
incompatible types
required: com.googlecode.objectify.Key<com.XX.XXXXXX.XXXXX.XXXXXX.Player>
found: com.googlecode.objectify.Key<java.lang.Object>

Related

Surprising "inferred type does not conform to upper bound" error

When i try to compile this cut-down example with a compiler from JDK 9, 10, or 11:
public class UpperBounder {
public static void main(String[] args) {
print(Stream.of("a", "z", "b").collect(Collectors.toCollection(TreeSet::new)));
}
static void print(Set<?> set) {
System.out.println(set);
}
}
I get this error:
error: incompatible types: inferred type does not conform to upper bound(s)
print(Stream.of("a", "z", "b").collect(Collectors.toCollection(TreeSet::new)));
^
inferred: INT#1
upper bound(s): Collection<String>,Set<?>,Object
where INT#1 is an intersection type:
INT#1 extends Object,Set<?>,Collection<String>
When i try to compile it with JDK 1.8.0_121, i get a different error. But when i or a colleague try to compile it with JDK 1.8.0_05, 1.8.0_20, 1.8.0_40, or 1.8.0_45, it compiles fine!
Replacing TreeSet::new with () -> new TreeSet<>() makes this compile without errors on all versions.
I think this program is clearly sound: the argument to print will be a TreeSet<String>, which conforms to Set<?>. Moreover, the error message makes no sense to me: an intersection type which is Object, Set<?>, and Collection<String> should conform to upper bounds which are Collection<String>, Set<?>, and Object!
What is going on? Is this a bug? Or is this how type inference is supposed to work? Why did it work before? How can i make it work again (without using a lambda instead of a method reference)?
This looks like bug: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8219318
As at 16/07/2019 Oracle has confirmed that they can reproduce this bug, but does not have a fix for it yet.
Both your test case and the one in the bug database can be reproduced using Oracle 1.8.0_191, both work fine in all tested versions using ecj (Eclipse).

"incompatible types" in foreach with jdk 1.7 - no error with 1.6

I have code similar to the following which compiles with jdk 1.6.0_22 but not with jdk 1.7.0_79:
for(Entry<A, B> entry: aBean.getData().entrySet()) { }
getData() returns a Map<A, B>. With 1.7 the following compile error occurs, suggesting that the generics of the returned Set are erased:
[compile] /path/to/file.java:170: error: incompatible types
[compile] for (Entry<A, B> entry: aBean.getData().entrySet()) {
[compile] ^
[compile] required: Entry<A, B>
[compile] found: Object
The error disappears when I use a local variable to hold the Set:
Set<Entry<A, B>> mySet = aBean.getData().entrySet();
for(Entry<A, B> entry: mySet) { } //works
Given that this compiles under 1.6, am I correct in assuming this is a compile Bug? If not, what am I doing wrong?
Have you already tested this with Java 8? If the issue still exists with the latest – and only supported – Java version, I suggest you create a bug report.
Otherwise use the solution you already provided in your question.

Convert a stream into a list

I want to convert a stream into a list. To do so I have tried this code :
try(Stream<String> stream = Files.lines(Paths.get(args[0]))) {
List<String> lines = stream.collect(Collectors.toList());
}
But then the compiler tell me that :
Type mismatch: cannot convert from List<Object> to List<String>
Also I've tried this way :
try(Stream<String> stream = Files.lines(Paths.get(args[0]))) {
List<String> lines = Stream.of(stream).collect(Collectors.toList());
}
But then I have this error :
This static method of interface Stream can only be accessed as Stream.of
which happen every time, whenever I use the Stream.of methods.
Can someone help me out, please?
It's seems that you use java compiler language level lower than 8.
Try compiling from command line with
javac -source 8
Also check your language level project setting in IDE.
For example, output from IDEA 2016 hides info about used language level, but provide info about javac version
Information:Using javac 1.8.0_101 to compile java sources
Information:java: Errors occurred while compiling module 'demo_04'
Information:8/1/16 2:13 PM - Compilation completed with 1 error and 0 warnings in 1s 403ms
/tmp/1/src/JavaStreamExample.java
Error:(16, 49) java: incompatible types: java.util.List<java.lang.Object> cannot be converted to java.util.List<java.lang.String>

javac incompatible types error in eclipse

While compiling the code I get an unexpected error, which never occurred before, it says that I cannot convert from int to an Object...
Code:
maxBundles = max;
bundleProgressBar.setMaximum(max);
bundleProgressLabel.setText("Updating Components...");
// Tell JS that the state is Installing.
Object[] arr = { 1 };
error:
`103: error: incompatible types
[javac] Object[] arr = { 1 };`
I know this is a problem with eclipse, because it worked before, so my question is what can I change to resolve it...
What you're trying to do is called autoboxing - the process of converting a primitive (int in this case) to its Object represantation (Integer in this case), automatically. More on autoboxing and unboxing here.
Autoboxing was introduced in Java 1.5. So check that your project's compiler compliance level is set to 1.5 or above (Project properties -> Java compiler).

JDK compiler error

Before anyone screams about EOL'ed JDK, I'd like to point out that my question is not about how to compile the following. There is a real question here and it's not about JDK 1.5 being EOL'ed...
The following under JDK 1.5, up to 1.5.0_22 (the last one I could find) produces on my system a compiler error:
private Object[] boozinga() {
boolean b = Math.abs(42) > 0;
Object[] res = new Object[1];
res[0] = b ? new int[1] : new String[1];
return res;
}
Changing the Math.abs(42) > 0 to true allows compilation.
Changing the ternary "assignment" to an if/else allows compilation.
Using JDK 1.6 allows compilation.
So I was wondering: is there something not legal in the above code under Java 1.5 and that is allowed under Java 1.6?
Does it crash for those of you that are under Java 1.5 too?
The crash says something like this:
An exception has occured in the
compiler (1.5.0_22). Please file a bug
at the Java Developer Connection
(http://java.sun.com/webapps/bugreport)
after checking the Bug Parade for
duplicates. Include your program and
the following diagnostic in your
report. Thank you.
I take it filling a bug report for an EOL'ed JDK is an exercice in futility but still, I'd still like to know if the above is valid Java 1.5 code or not.
I think it is legal. The evidence is that JDK 1.6.0_21 compiles it with options -source 1.5 -target 1.5. Can't you use JDK 1.6 with these options to compile and JRE 1.5 to run?
It crashes for me, too (JDK 1.5.0_12). It crashes for me even with:
public Object boozinga() {
boolean b = true;
Object res = b ? new int[1] : new String[1];
return res;
}
The difficulty for the compiler is that the type of b ? new int[1] : new String[1] is java.lang.Object & java.io.Serializable & java.lang.Cloneable.
The problem here is that the compiler has trouble to decide the type of the expression b ? new int[1] : new String[1]. I had something like this before (with 1.1.8 or 1.2, I think - but with a real error message, not a compiler crash), and then simply used a cast to help the compiler here.
res[0] = b ? (Object)new int[1] : new String[1];
I didn't look what the language specification says about this - but the compiler should never crash with an exception, it should give a real error message.

Categories

Resources