NoClassDefFoundError: com/pi4j/io/I2CFactory$UnsupportedBusNumberException
Я пытаюсь запустить Java-код на Raspberry Pi model 3, загруженный из среды разработки PC eclipse, чтобы получить доступ к устройству 9DoF на шине I2C с помощью библиотеки pi4j. Я получаю следующую ошибку:
java -classpath.: classes: / opt / pi4j / lib / '*' -jar / home / pi
/artifacts/RPITank-1.0-SNAPSHOT.jar Ошибка: произошла ошибка JNI, проверьте вашу установку и повторите попытку. Исключение в потоке "main" java.lang.NoClassDefFoundError: com / pi4j / io / i2c / I2CFa
ctory $ UnsupportedBusNumberException в java.lang.Class.getDeclaredMethods0(собственный метод) в java.lang.Class.privateGetDeclaredMethods(Class.java:2701) в java.lang.Class.privateGetMethodRecursive(Class.javag java).Class.getMethod0(Class.java:3018) в java.lang.Class.getMethod(Class.java:1784) в sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544) в sun.launcher.LauncherHelper.HackAnd.java:526) Причина: java.lang.ClassNotFoundException: com.pi4j.io.i2c.I2CFactory $ Unsuppor
tedBusNumberException в java.net.URLClassLoader.findClass(URLClassLoader.java:381) в java.lang.ClassLoader.loadClass(ClassLoader.java:424) в sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:1).lang.ClassLoader.loadClass(ClassLoader.java:357) ... еще 7
Это код
package main;
import java.io.IOException;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.i2c.I2CBus;
import com.pi4j.io.i2c.I2CFactory;
import devices.I2C.Pi4jI2CDevice;
import devices.sensorImplementations.MPU9250.MPU9250;
public class MPU9250Test {
public static void main(String[] args)
{
I2CBus bus = null;
System.out.println("Attempt to get Bus 1");
try {
final GpioController gpio = GpioFactory.getInstance();
bus = I2CFactory.getInstance(I2CBus.BUS_1);
System.out.println("Got Bus, create devices");
MPU9250 mpu9250 = new MPU9250(
new Pi4jI2CDevice(bus.getDevice(0x68)), // MPU9250 I2C device
new Pi4jI2CDevice(bus.getDevice(0x0C)), // ak8963 I2C
100, // sample rate
100); // sample size
Thread sensor = new Thread(mpu9250);
sensor.start();
Thread.sleep(10000);
sensor.interrupt();
for(int i = mpu9250.getAccelerometerReadingCount() -1; i>0; i--)
{
System.out.print("G: " + mpu9250.getRotationalAcceleration(i).toString());
System.out.print(" A: " + mpu9250.getAcceleration(i).toString());
System.out.println(" M: " + mpu9250.getGaussianData(i).toString());
}
} catch (I2CFactory.UnsupportedBusNumberException | InterruptedException | IOException e) {
e.printStackTrace();
}
}
}
Я проверил, что устройство видимо на шине 1, используя I2Cdetect -y 1, это показывает устройство по адресам 0x68 и 0x76.
Я не знаю, если это проблема со средой выполнения или кодом, любая помощь будет приветствоваться.
Дальнейшие эксперименты показывают, что удаление обработчика исключений не является опцией, которая требуется во время компиляции. Класс исключения описан здесь http://pi4j.com/apidocs/com/pi4j/io/i2c/I2CFactory.UnsupportedBusNumberException.html
1 ответ
Проблема заключалась в том, что jar проекта при переносе в Raspberry Pi не собирал ссылки во время выполнения с программным обеспечением pi4j, предустановленным на RPi, проблема была решена с помощью проблемы на github здесь благодаря natdan.
Внесены следующие изменения в проект pom.xml:
Добавьте зависимость времени выполнения к зависимостям
<dependencies>
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-core</artifactId>
<version>1.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-native</artifactId>
<version>1.2-SNAPSHOT</version>
<classifier>raspberrypi-dynamic</classifier>
<type>so</type>
</dependency>
После дальнейших экспериментов выяснилось, что эта зависимость, в конце концов, не нужна, поэтому проигнорируйте приведенный выше раздел.
Путь к классу был добавлен в конфигурацию плагина maven jar как запись манифеста:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<!--<classpathPrefix>${pi.pi4j.Directory}/</classpathPrefix>-->
<mainClass>${pi.main.class}</mainClass>
</manifest>
<manifestEntries>
<!-- Add the pi4j in runtime. -->
<Class-Path>${pi.pi4j.Directory}/pi4j-core.jar</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
наконец, classpath был удален из команды java в секции antrun
<!-- run the JAR file on the Raspberry Pi -->
<sshexec host="${pi.host}" port="${pi.port}" username="${pi.user}"
password="${pi.password}" trust="true" failonerror="false"
verbose="true"
command="java -jar ${pi.deployDirectory}/${project.build.finalName}.jar" />