java generics: ошибка компилятора не отображается в eclipse

У меня есть такие занятия:

public class EntityDataModel<T extends AbstractEntity>
{
    ...
}

public abstract class BarChartBean<E extends ChartEntry, T>
{
    protected EntityDataModel<? extends T> currentModel;

    ...
}

Я могу скомпилировать и запустить этот код в eclipse без проблем, но когда я вызываю mvn compile, выдается эта ошибка:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.5.1:compile (default-compile) on project edea2: Compilation failure: Compilation failure:
[ERROR] C:\Develop\...\BarChartBean.java:[53,30] error: type argument ? extends T#1 is not within bounds of type-variable T#2
[ERROR] where T#1,T#2 are type-variables:
[ERROR] T#1 extends Object declared in class BarChartBean
[ERROR] T#2 extends AbstractEntity declared in class EntityDataModel

Ошибка довольно очевидна, и, теоретически говоря, javac правильный, а компилятор eclipse неправильный.

Почему такая разница?

Вот подробности об окружающей среде:

  • Затмение

    • Mars.2 Release (4.5.2)
    • jdk 1.8.0_71
    • Уровень соответствия компилятора: 1.8
    • «Ошибки
  • Maven

    • Apache Maven 3.3.3 (7994120775791599e205a5524ec3e0dfe41d4a06; 2015-04-22T13:57:37+02:00)
    • Домашняя страница Maven: C: \ Develop \ tools \ apache-maven-3.3.3
    • Версия Java: 1.8.0_71, поставщик: Oracle Corporation
    • Домашняя страница Java: C: \ Program Files \ Java \ jdk1.8.0_71 \ jre
    • Локаль по умолчанию: it_IT, кодировка платформы: Cp1252
    • Название ОС: "windows 10", версия: "10.0", арка: "amd64", семейство: "dos"
    • плагин компилятора maven:

      <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>2.5.1</version>
          <configuration>
              <source>1.8</source>
              <target>1.8</target>
              <encoding>UTF-8</encoding>
              <showDeprecation>true</showDeprecation>
              <showWarnings>true</showWarnings>
          </configuration>
      </plugin>
      

Вопрос: как я могу согласовать поведение компилятора eclipse с javac (но я не хочу использовать javac в eclipse)?


person Michele Mariotti    schedule 28.06.2016    source источник


Ответы (1)


Это еще одно несоответствие между компилятором Eclipse Java и официальным компилятором JDK (потому что они действительно разные). И javac не всегда является правом в этой игре, вы действительно можете столкнуться с ошибкой javac, которая не возникает в компиляторе Eclipse.

О подобной проблеме уже сообщалось: Ошибка 456459: Несоответствие между компилятором Eclipse и javac - перечисления, интерфейсы и обобщения.

Чтобы согласовать Maven с Eclipse, вы можете настроить maven-compiler-plugin следующим образом:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.5.1</version>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <compilerId>eclipse</compilerId>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>org.codehaus.plexus</groupId>
            <artifactId>plexus-compiler-eclipse</artifactId>
            <version>2.7</version>
        </dependency>
    </dependencies>
</plugin>

По сути, вы говорите Maven использовать компилятор Eclipse Java. Мне удалось воспроизвести вашу проблему, и, применив эту конфигурацию, сборка Maven была в порядке. Однако я бы не рекомендовал такой подход.

С другой стороны, настроить Eclipse для использования компилятора JDK немного сложнее, в основном потому, что компилятор Eclipse является частью функций IDE. Процедура объясняется в Q / A переполнении стека: Как запустить Javac из Eclipse .

person A_Di-Matteo    schedule 28.06.2016
comment
@MicheleMariotti, спасибо за сообщение об ошибке. Как там утверждается, я не уверен, что ecj ошибочен. JLS 4.5 определяет корректность параметризованного типа через захват аргументов типа. Такой захват по определению соответствует верхним границам соответствующей переменной типа. Итак, как cap#1 extends glb(AbstractEntity,T) нарушить границу extends AbstractEntity? Этот тип может быть неправильно сформирован из-за противоречивых границ (например, undefined glb), но я не вижу такого противоречия. Итак, почему компилятор должен отклонять это? - person Stephan Herrmann; 28.06.2016
comment
Относительно plexus-compiler-eclipse: я не уверен, как поддерживается этот плагин и какие версии ecj он будет использовать. Дополнительные советы по использованию ecj вне Eclipse собраны на wiki.eclipse.org/JDT/, который включает опцию использования tycho, которая регулярно обновляет ecj-зависимость. - person Stephan Herrmann; 28.06.2016
comment
@StephanHerrmann Я обязательно посмотрю. Еще раз спасибо :) - person Michele Mariotti; 28.06.2016