如何在包含本机代码的Java应用程序中使用命令行执行Maven主类?

时间:2017-07-21 06:31:50

标签: java eclipse maven

我想使用命令行执行我的maven项目独立类。

JnetSampleTest.java -

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.jnetpcap.Pcap;
import org.jnetpcap.PcapIf;
import org.jnetpcap.packet.PcapPacket;
import org.jnetpcap.packet.PcapPacketHandler;

public class JnetSampleTest {

    public static void main(String[] args) {

        List<PcapIf> alldevs = new ArrayList<PcapIf>(); // Will be filled with NICs
        StringBuilder errbuf = new StringBuilder(); // For any error msgs

        int r = Pcap.findAllDevs(alldevs, errbuf);
        if (r == Pcap.NOT_OK || alldevs.isEmpty()) {
            System.err.printf("Can't read list of devices, error is %s", errbuf.toString());
            return;
        }

        System.out.println("Network devices found:");

        int i = 0;
        for (PcapIf device : alldevs) {
            String description = (device.getDescription() != null) ? device.getDescription()
                    : "No description available";
            System.out.printf("#%d: %s [%s]\n", i++, device.getName(), description);
        }

        PcapIf device = alldevs.get(8); // We know we have atleast 1 device
        PcapIf d = new PcapIf();

        System.out.printf("\nChoosing '%s' on your behalf:\n",
                (device.getDescription() != null) ? device.getDescription() : device.getName());

        int snaplen = 64 * 1024; // Capture all packets, no trucation
        int flags = Pcap.MODE_PROMISCUOUS; // capture all packets
        int timeout = 10 * 1000; // 10 seconds in millis
        Pcap pcap = Pcap.openLive(device.getName(), snaplen, flags, timeout, errbuf);

        if (pcap == null) {
            System.err.printf("Error while opening device for capture: " + errbuf.toString());
            return;
        }

        PcapPacketHandler<String> jpacketHandler = new PcapPacketHandler<String>() {
            public void nextPacket(PcapPacket packet, String user) {
                System.out.printf("Received packet at %s caplen=%-4d len=%-4d %s\n",
                        new Date(packet.getCaptureHeader().timestampInMillis()), packet.getCaptureHeader().caplen(), // Length
                        packet.getCaptureHeader().wirelen(), // Original length
                        user // User supplied object
                );
            }
        };

        pcap.loop(10, jpacketHandler, "jNetPcap rocks!");
        pcap.close();
    }
}

我按照this tutorial创建了jnetpcap的用户库,并将其添加到项目中。

在eclipse中,这段代码运行正常,但我想使用命令行执行此代码,所以我在pom.xml中添加了下面的示例代码 -

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.2.1</version>
            <executions>
                <execution>
                    <goals>
                        <goal>java</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <mainClass>com.JnetSampleTest.JnetSampleTest</mainClass>
            </configuration>
        </plugin>
    </plugins>
</build>

我尝试过这个命令来执行我的主类 -

mvn exec:java -Dexec.mainClass="com.JnetSampleTest.JnetSampleTest"

我得到了这个例外 -

[WARNING] 
java.lang.reflect.InvocationTargetException
    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.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:297)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.UnsatisfiedLinkError: com.slytechs.library.NativeLibrary.dlopen(Ljava/lang/String;)J
    at com.slytechs.library.NativeLibrary.dlopen(Native Method)
    at com.slytechs.library.NativeLibrary.<init>(Unknown Source)
    at com.slytechs.library.JNILibrary.<init>(Unknown Source)
    at com.slytechs.library.JNILibrary.loadLibrary(Unknown Source)
    at com.slytechs.library.JNILibrary.register(Unknown Source)
    at com.slytechs.library.JNILibrary.register(Unknown Source)
    at com.slytechs.library.JNILibrary.register(Unknown Source)
    at org.jnetpcap.Pcap.<clinit>(Unknown Source)

如何使用命令行执行此类?

2 个答案:

答案 0 :(得分:0)

缺少本机库。可能是x86与x64问题。

答案 1 :(得分:0)

当找不到代码正在查找的so / dll文件时,会发生此类错误。请确保将jnetpcap的.dll文件保存在windows system32文件夹中。

IntelliJ的过程应该类似于jnetpcap.com/?q=eclipse(或NetBeans)的过程。我不熟悉IntelliJ,但是......你可以尝试将本机库(Linux上的.so文件,Windows上的.dll文件,Mac上的.dylib文件)复制到项目的主目录中。 / p>