Pi4j使用java与树莓Pi不工作



我真的要放弃了,我已经尝试了很多不同的可能性,好几个星期了,差不多一个月了,有很多问题。

我是一个新的ish程序员,尤其是java程序员,但我对java有很好的理解

我能够创建一个maven项目,没有问题,我对java本身的结构没有问题,但我不完全理解pom.xml。

该文件编译得很好,但当我用java -jar (filename)启动它时,我会得到以下输出;

线程中的异常"主";java.lang.NoClassDefFoundError:com/pi4j/pi4j网址:com.pi.raserri.Main.Main(Main.java:16)引起原因:java.lang.ClassNotFoundException:com.pi4j.pi4j位于java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)位于java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)位于java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)…还有1个

这是我几乎被肢解的pom;

(The long links)
<modelVersion>4.0.0</modelVersion>
<groupId>com.pi</groupId>
<artifactId>Rasberri</artifactId>
<version>3.6.1</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>  <dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.32</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
</dependency>
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-core</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-plugin-raspberrypi</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-plugin-pigpio</artifactId>
<version>2.0</version>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2</version> </plugin>    <plugin>    <groupId>org.apache.maven.plugins</groupId>   

maven jar插件3.1.0真的com.pi.rasberri.Mainlib/真的真的com.pi.rasberri.Main虚假的真的

还有我的代码,它是com.pi.rasberri.Main

package com.pi.rasberri;
import com.pi4j.Pi4J;
import com.pi4j.io.gpio.digital.DigitalOutput;
import com.pi4j.io.gpio.digital.DigitalState;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Main {

private static final int PIN_LED = 6;

public static void main(String[] args) throws Exception{

var pi4j = Pi4J.newAutoContext();
int x = 0;

var ledConfig = DigitalOutput.newConfigBuilder(pi4j)
.id("led")
.name("LED Flasher")
.address(PIN_LED)
.shutdown(DigitalState.LOW)
.initial(DigitalState.LOW)
.provider("pigpio-digital-output");

var led = pi4j.create(ledConfig);


while(x != 5){

led.high();
sleep(1000);
led.low();
sleep(500);
x++;
}
}

static void sleep(int z){

try {
Thread.sleep(z);
}   catch (InterruptedException ex) {
System.out.println("Thread.sleep went fucky wucky");
}
}
}

我会感谢任何能指引我去某个地方的东西,因为我在这一点上很失落,当然,如果我找到答案,我会让每个人都知道的!提前感谢

**UPDATE**

谢谢你,tgdavies,你链接的文章https://stackoverflow.com/a/574650/17644313就是答案具体问题!**

以防其他人和我有同样的问题链

但话虽如此,我直接遇到了另一个错误

[main]INFO com.pi4j.pi4j-新的自动上下文〔main〕INFO com.pi4j.pi4j-新的上下文生成器[min]INFO com.pi4j.platform.impl.DefaultRuntimePlatforms-将平台添加到托管平台映射[id=raspberrrypi;name=raspberrypi platform;优先级=5;class=com.pi4j.plugin.raspberrypi.platform.RapsberyPiPlatform]线程中的异常";主";com.pi4j.provider.exception.ProviderNotFoundException:找不到pi4j提供程序[pigpio数字输出]。请在类路径中包含这个"provider"JAR。网址:com.pi4j.provider.impl.DefaultRuntimeProviders.get(DefaultRuntimeProvider.java:238)网址:com.pi4j.provider.impl.DefaultProviders.get(DefaultProviders.java:147)网址:com.pi4j.provider.Providers.get(Providers.java:253)网址:com.pi4j.context.context.create(context.java:316)网址:com.pi4j.internal.IOCreator.create(IOCreator.java:58)网址:com.pi4j.internal.IOCreator.create(IOCreator.java:96)网址:com.pi4j.internal.IOCreator.create(IOCreator.java:176)网址:com.pi.raserri.Main.Main(Main.java:27)

我稍微清理了pom.xml;

<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.32</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-core</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-plugin-raspberrypi</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-plugin-pigpio</artifactId>
<version>2.0</version>
</dependency>
</dependencies>

<build>
<plugins>  <!--Package all libraries classes into one runnable jar -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<mainClass>com.pi.rasberri.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>    
</plugins>
</build>
</project>

在这一点上,我知道至少有两种可能性,

  1. 代码只需要在树莓pi上运行
  2. 我输入的类路径不正确

但我真的不知道从哪里开始排除故障我尝试了一些方法,其中之一是尝试另一种编译文件的方法,但另一种方法只会导致更长的错误串。

我下一步该怎么做?提前感谢!感谢迄今为止提出故障排除步骤的任何人!

哦,目标是希望只创建一个单独的jar文件,在树莓pi 上执行

更新

我试图在Raspberri pi上运行它,但它导致了相同的错误,所以它不是

我没有树莓派来做最终测试,但我想我找到了解决办法。

使用这个答案,我设法使2021-10-30-raspios-bullseye-armhf-lite.img在Docker中运行。我用你的代码构建了一个项目,复制了所有需要的文件,并试图启动它(mypiapp是我的jar,包含你的主类):

java -cp mypiapp-0.0.1-SNAPSHOT.jar:lib/pi4j-core-2.1.1.jar:lib/pi4j-library-pigpio-2.1.1.jar:lib/pi4j-plugin-pigpio-2.1.1.jar:lib/pi4j-plugin-raspberrypi-2.1.1.jar:lib/slf4j-api-1.7.32.jar:lib/slf4j-simple-1.7.32.jar com.github.fwi.mypiapp.MyPiApp

然后给了我一个错误:

[main] ERROR com.pi4j.library.pigpio.util.NativeLibraryLoader - Unable to load [libpi4j-pigpio.so] using path: [/lib/armhf/libpi4j-pigpio.so]
java.lang.UnsatisfiedLinkError: /tmp/libpi4j-pigpio1770932771276400506.so: libpigpio.so.1: cannot open shared object file: No such file or directory

这太令人沮丧了。但至少没有ProviderNotFoundException(我也可以使用"有依赖关系的胖罐子"来复制它)。出现长java命令是为了防止发生该异常。

我可以通过运行(在Raspbian)在一定程度上改善这种情况

apt install pigpio

现在长的java命令显示:

[main] WARN com.pi4j.library.pigpio.impl.PiGpioNativeImpl - PIGPIO ERROR: PI_INIT_FAILED; pigpio initialisation failed

这是在Docker容器中运行时所期望的。但至少找到并加载了本机库。

现在,对于可能解决";胖罐子";问题。我们将借用Spring中的一些Maven设置和代码。Spring也可以制作肥罐子,它做得更复杂,但也更好。pom现在看起来像(在需要的地方用你的项目名称更新):

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.1</version>
</parent>

<groupId>com.github.fwi</groupId>
<artifactId>mypiapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>11</java.version>
<start.class>com.github.fwi.mypiapp.MyPiApp</start.class>
<pi4j.version>2.1.1</pi4j.version>
</properties>
<dependencies>
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-plugin-raspberrypi</artifactId>
<version>${pi4j.version}</version>
</dependency>
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-plugin-pigpio</artifactId>
<version>${pi4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>${start.class}</mainClass>
<layout>ZIP</layout>
<executable>false</executable>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

只需运行mvn clean package即可构建胖罐子。使用java -jar mypiapp-fat.jar运行它。在我的情况下,它给出的错误与使用长java命令运行时完全相同(即没有ProviderNotFoundException)。所以我认为这可以在真正的树莓派上工作(尽管可能仍然需要apt install pigpio)。

一些注意事项:

  • Spring父级设置了一些好的Maven默认值,也为spring-boot-maven-plugin设置了好的默认值
  • Java版本必须使用java.version属性进行设置
  • 使用包含main-方法的类的名称更新start.class
  • CCD_ 13中的3个依赖项将引入所有其他依赖项(依赖项的依赖项)
  • Spring文档参考:打包和嵌套jar启动器选项

我在使用Raspberry P4、java 11和pi4j v2时遇到了同样的问题。我解决了直接从树莓下载pigpio库的问题

sudo apt-get install pigpio

图书馆安装好后,罐子工作得很好。如果您不是的root用户,请记住使用sudo运行程序

感谢tgdavies、MadProgrammer和khmarbaise的回答,修复方法是创建一个胖jar,它基本上是一个jar文件,包含一个文件中的所有依赖项。示例可以在原始问题/评论中找到

更新

Pi4j已经在他们的网站上发布了V2脂肪罐的说明!我试过了,现在效果很好

https://pi4j.com/getting-started/minimal-example-application-fatjar/

最新更新