Sun javac / Eclipse compiler difference
Our primary development environment is Eclipse 3.3.1.1, set to Java 5 compatibility. However during the nightly builds we use Sun's javac, currently version 1.5.0_12 I believe.
Today I noticed one of the builds had failed in this code (reduced to a small test case):
public interface Task<V> {}
public interface RunnableTask extends Runnable, Task {}
public class ProgressMonitorUtil { public <V> V execute(final Task<V> aBackgroundTask) { return null; } public void execute(final RunnableTask aBackgroundTask) {} }
public class Test { public static void main(String[] args) { new ProgressMonitorUtil().execute(new RunnableTask() { public void run() {} }); } }
Put these classes into an Eclipse project, either with Java 5 or Java 6 compatibility settings. You will see no problems. However compiling this with Sun's javac (also either 5 or 6 will do) leads to this:
Test.java:4: reference to execute is ambiguous, both method <V>execute(Task<V>) in ProgressMonitorUtil and method execute(RunnableTask) in ProgressMonitorUtil match new ProgressMonitorUtil().execute(new RunnableTask() { Note: Test.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 1 error
Apparently method dispatching works differently in both compilers. In Eclipse the call goes to the second method (void execute...
) which seems reasonable since RunnableTask
is a more specific type.
However you can still convince Sun's compiler to compile this if you get rid of the "unchecked" warnings:
public interface RunnableTask extends Runnable, Task<Void> {}
public class ProgressMonitorUtil { public <V> V execute(final Task<V> aBackgroundTask) { return null; } public void execute(final RunnableTask aBackgroundTask) {} }
public class Test { public static void main(String[] args) { new ProgressMonitorUtil().execute(new RunnableTask() { public void run() {} }); } }
This compiles without warnings or errors on both compilers and leads to the same dispatching that Eclipse does. I guess I will post this as an Eclipse bug nevertheless, because responses there are usually way quicker than at Sun...
Edit: Making RunnableTask generic is not very useful in this context, but instead just declaring it as "extends Task<Void>" is sufficient as well. I updated the samples above.
Comments
XPathExpression expr = xpath.compile("//root/element");
inputSource.getByteStream().reset(); // this has to be done to avoid the error "org.xml.sax.SAXEception: Premature end of file"
value = (String)expr.evaluate(inputSource, XPathConstants.STRING);
Then you are able to call evaluate method more than once.
did you post a bug for this issue and/or have you heared something about it?