Ошибка компиляции, когда не переопределяется реализация интерфейса по умолчанию - PullRequest
1 голос
/ 03 октября 2019

Я пытаюсь реализовать org.apache.spark.sql.Row. Интерфейс имеет реализации по умолчанию для нескольких методов, и IntelliJ не жалуется, что не переопределяет эти методы. Однако при сборке с помощью maven я получаю:

FunctionalRow is not abstract and does not override abstract method mkString(java.lang.String,java.lang.String,java.lang.String) in org.apache.spark.sql.Row

Ниже приведена реализация класса:

import java.util.List;
import java.util.function.Supplier;

import org.apache.spark.sql.Row;

import scala.collection.JavaConverters;
import scala.collection.Seq;

public class FunctionalRow implements Row {
    protected List<Supplier<Object>> suppliers;

    public FunctionalRow(List<Supplier<Object>> suppliers) {
        this.suppliers = suppliers;
    }

    @Override
    public int length() {
        return suppliers.size();
    }

    @Override
    public Object get(int i) {
        return suppliers.get(i).get();
    }

    @Override
    public Row copy() {
        return this;
    }

    @Override
    public Seq<Object> toSeq() {
        return JavaConverters.asScalaIteratorConverter(suppliers.stream().map(s -> s.get()).iterator()).asScala().toSeq();
    }
}

Параметры подключаемого модуля maven-compiler-*:

        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
          <executions>
            <execution>
              <id>default-compile</id>
              <phase>compile</phase>
              <goals>
                <goal>compile</goal>
              </goals>
              <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>UTF-8</encoding>
              </configuration>
            </execution>
            <execution>
              <id>default-testCompile</id>
              <phase>test-compile</phase>
              <goals>
                <goal>testCompile</goal>
              </goals>
              <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>UTF-8</encoding>
              </configuration>
            </execution>
          </executions>
          <configuration>
            <source>1.8</source>
            <target>1.8</target>
            <encoding>UTF-8</encoding>
          </configuration>
        </plugin>

Любая помощь будет оценена!

1 Ответ

0 голосов
/ 03 октября 2019

Я превращаю свой комментарий в ответ, чтобы вы могли пометить этот вопрос как ответ.

TL; DR: Вы не можете использовать реализацию по умолчанию для черт Scala в Java, если черта быласоставлен версией Scala ранее 2.12. Это относится к используемой здесь версии Spark, поэтому вся надежда потеряна.

Причина заключается в том, как компилятор Scala кодирует признаки для совместимости с JVM (и, следовательно, с Java). ,

До Java 8 интерфейсам не разрешалось предоставлять реализации по умолчанию. Черты Scala, которые являются в основном стековыми интерфейсами с реализациями по умолчанию, должны быть закодированы как с интерфейсом без реализации, так и с абстрактным классом, обеспечивающим реализацию. Подробнее об этом см. этот ответ .

После Java 8 интерфейсам было разрешено предоставлять реализацию по умолчанию, поэтому Scala могла кодировать признаки с реализациями по умолчанию прямо вJava-интерфейсы и быть напрямую совместимыми с Java-кодом. Начиная с Scala 2.12, для Scala требуется совместимая с Java 8+ JVM, что обеспечивает совместимость с чертами <->. Если код Scala был скомпилирован компилятором Scala 2.12+, вы можете использовать его черты как обычные интерфейсы Java.

...