Как мне импортировать одноэлементный объект из пакета Scala в Java?

#java #scala #apache-spark

#java #scala #apache-spark

Вопрос:

Я пытаюсь использовать объект ARIMA (Scala), который импортируется из пакета, в моей Java-программе. Хотя компиляция завершается успешно, что означает, что класс ARIMA распознается во время компиляции, для объекта ARIMA во время выполнения существует NoClassDefFoundErrorNoClassDefFoundError. У класса ARIMAModel нет проблем с импортом, поскольку это класс.

Есть ли какой-либо способ использовать объект Scala из моей Java-программы?

Вот исходный код для объекта в пакете Scala.

Файл: …/com/cloudera/sparkts/models/ARIMA.scala

 package com.cloudera.sparkts.models

object ARIMA {
    def autoFit(ts: Vector, maxP: Int = 5, maxD: Int = 2, maxQ: Int = 5): ARIMAModel = {
        ...
    }
}

class ARIMAModel(...) {
    ...
}
  

Вот мой Java-код.

Файл: src/main/java/SingleSeriesARIMA.java

 import com.cloudera.sparkts.models.ARIMA;
import com.cloudera.sparkts.models.ARIMAModel;

public class SingleSeriesARIMA {
    public static void main(String[] args) {
        ... 
        ARIMAModel arimaModel = ARIMA.autoFit(tsVector, 1, 0, 1);
        ...
    }
}
  

Вот ошибка.

 Exception in thread "main" java.lang.NoClassDefFoundError: com/cloudera/sparkts/models/ARIMA
at SingleSeriesARIMA.main(SingleSeriesARIMA.java:43)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:729)
at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:185)
at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:210)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:124)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
Caused by: java.lang.ClassNotFoundException: com.cloudera.sparkts.models.ARIMA
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 10 more
  

Я использую Scala версии 2.11.8 и Java 1.8

Комментарии:

1. Если он скомпилирован, значит, код правильный. — java.lang.NoClassDefFoundError: com/cloudera/sparkts/models/ARIMA это означает, что jar , содержащий этот класс, не присутствовал во время выполнения. Мы не сможем вам помочь, если вы не объясните, где находится этот jar и как di вы включили в среду выполнения.

2. Я понимаю. Я использую maven для сборки и выполнения программы. Зависимость от пакета sparkts включена в файл POM. Для компиляции я использовал пакет mvn . Затем я выполнил spark-submit —class «SingleSeriesARIMA» target/simple-project-1.0.jar для его запуска.

Ответ №1:

Вам нужно предоставить зависимость, имеющую Arima объект, присутствующий в кластере spark, используя --jars опцию, как показано ниже-

 spark-submit --jars <path>/<to>/sparkts-0.4.1.jar --class SingleSeriesARIMA target/simple-project-1.0.jar
  

Это передаст другую зависимость вместе с jar-файлом приложения, который будет доступен по адресу spark-runtime .

ДЛЯ вызова ARIMA объекта из java используйте-

 ARIMA$.MODULE$.autoFit(tsVector, 1, 0, 1);
  

Комментарии:

1. Теперь это работает! Я понял, что забыл указать jar в качестве его зависимости.

2. Пожалуйста, не стесняйтесь голосовать принять, если это поможет meta.stackexchange.com/a/5235/767994