Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how come Eclipse compiles this Java code but not Ant?

This compiles find using Eclipse:

abstract class CollectionView implements Collection<Object> {

...
        public Object[] toArray(Object[] o) {
            if (fast) {
                return get(map).toArray(o);
            } else {
                synchronized (map) {
                    return get(map).toArray(o);
                }
            }
        }
...
}

    class KeySet extends CollectionView implements Set<Object> {

        protected Collection<Object> get(Map<Object, Object> map) {
            return map.keySet();
        }

        protected Object iteratorNext(Map.Entry entry) {
            return entry.getKey();
        }   
    }

but it fails to compile when using Ant:

error: KeySet is not abstract and does not override abstract method toArray(T[]) in Set

I can see why the code would compile using Eclipse: KeySet already inherits the implementation of the toArray(T[]) method from CollectionView.

But why does it fail when I compile using Ant?

    <javac srcdir="src" destdir="bin" debug="on"> 
        <compilerarg value="-Xlint:unchecked"/>
        <compilerarg value="-Xlint:deprecation"/>
    </javac>
like image 871
J Smith Avatar asked Jun 11 '13 17:06

J Smith


2 Answers

First we should note the exact signature of the method expected to be implemented is:

<T> T[] toArray(T[] a);

And both javac and Eclipse do warn you about this 'Type safety' issue. And if you change the signature to be the expected one, javac is happy.

If you put an @Override to the method toArray, even with the signature which use raw Object type, both Eclipse and javac correctly see it as an override of the method declared by Collection. So this issue is not there.

The inconsistency, and I think the bug of javac, is that is any subclass implementation, javac doesn't recognize the super method Object[] toArray(Object[] o) to implement <T> T[] toArray(T[] a). If it did for the abstract class, i should also do it for every subclass.

It is not the first time javac has a bug about this. See this thread for instance. I have searched the Oracle bug database, I found nothing reported about what you have found.

Then there are a work around: in the abstrcat class, use the expected signature; Or do the override 'manually` in the subclasss:

public Object[] toArray(Object[] o) {
    return super.toArray(o);
}
like image 155
Nicolas Lalevée Avatar answered Sep 27 '22 23:09

Nicolas Lalevée


There are several cases where eclipse compiles fine and javac doesn't. If you do not mind, there are three ways that I know to build using the eclipse compiler.

  1. Package eclipse pre-compiled classes (hacky, NOT recommended)

  2. Use the eclipse compiler adapter with Ant. When you specify the property build.compiler, all javac tasks henceforth will be affected on your Ant build. You can set it to "org.eclipse.jdt.core.JDTCompilerAdapter". Note that you will have to include this class (and classes it depends on) in your ant build classpath. The most straightforward way is to add the necessary jars to the lib folder of your Ant installation

  3. When building with maven configure this

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <compilerId>eclipse</compilerId>
                    <compilerVersion>1.6</compilerVersion>
                    <source>1.6</source>
                    <target>1.6</target>
                    <optimize>true</optimize>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.codehaus.plexus</groupId>
                        <artifactId>plexus-compiler-eclipse</artifactId>
                        <version>2.2</version>
                    </dependency>
                </dependencies>
            </plugin>
    

in the plugins section of the build section of your pom.xml

like image 45
dkateros Avatar answered Sep 28 '22 00:09

dkateros