2

I created one maven project in which only one class is available. I want to use jnetpcap API in this class. For this purpose, I followed jnet eclipse setup tutorial with Setup 1 approach (user library) and created one user library and added it to my project.

JnetTest.java - This class is same as jnetpcap clasic example

My system is Ubuntu 16.10.

I'm using openjdk version "1.8.0_131".

Library creation steps -

  1. I downloaded 1.3 version jar package, source package and javadoc package of jnetpcap and added libjnetpcap.so, jnetpcap.jar, jnetpcap-src-1.3.zip, jnetpcap-javadoc-1.3.zip to lib folder created under main project folder.
  2. created new library. Java-> Build Path -> User Libraries -> New -> Give Any Name.
  3. Add jar file. Add external jars -> workspace radio button -> selected lib/jnetpcap.jar
  4. fulfill the required dependency. expand jar -> source -> edit -> selected lib/jnetpcap-src-1.3.zip. javadoc -> edit -> selected lib/jnetpcap-javadoc-1.3.zip. Native library location -> edit -> selected lib directory. -> APPLY -> OK
  5. add library to project. right click on project -> Build Path -> Configure Build Path -> Libraries -> Add Library -> User Library -> select newly created library.

Note - I didn't added vm argument to my main class. i.e. -Djava.library.path="location to parent directory of .so file"

After that I right click on my project and clicked on a run as a java application. This will work in eclipse fine.

Actual problem - I want to run this maven project on one different machine with command line only. How I can run this project using command line?

My approach -

  1. I added below plugin in pom.xml for main class configuration.

    <!-- language: lang-xml -->
    <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.example.Main</mainClass>
       </configuration>
    </plugin>
    
  2. I used mvn exec command to run my main class

    mvn exec:java -Dexec.mainClass="com.example.Main"
    

But I got below exception -

Exception in thread "main" 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.(Unknown Source)
at com.slytechs.library.JNILibrary.(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.(Unknown Source)

My approach is correct or not to execute my project's main class? If yes then what will be the solution to my problem? If no please suggest useful approach.

ketan
  • 2,186
  • 6
  • 20
  • 64

2 Answers2

1

I don't have your exact code bu I think you are looking for this.

http://www.mojohaus.org/exec-maven-plugin/examples/example-exec-using-plugin-dependencies.html

Below marked section is the one where you can put dependencies required by your main class. I hope this works.

    <project>
      ...
      <build>
        <plugins>
          <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.6.0</version>
            <executions>
              <execution>
                ...
                <goals>
                  <goal>java</goal>
                </goals>
              </execution>
            </executions>
            <configuration>
              <includeProjectDependencies>false</includeProjectDependencies>
              <includePluginDependencies>true</includePluginDependencies>
              <executableDependency>
                <groupId>com.example.myproject</groupId>
                <artifactId>mylib</artifactId>
              </executableDependency>
              <mainClass>com.example.Main</mainClass>
              <arguments>
                <argument>argument1</argument>
                ...
              </arguments>
              <systemProperties>
                <systemProperty>
                  <key>myproperty</key>
                  <value>myvalue</value>
                </systemProperty>
                ...
              </systemProperties>
            </configuration>
<!-- This is where you put dependencies needed for main class-->
            <dependencies>
              <dependency>
                <groupId>com.example.myproject</groupId>
                <artifactId>mylib</artifactId>
                <version>1.3.5</version>
                <type>jar</type>
              </dependency>
            </dependencies>
          </plugin>
        </plugins>
      </build>
       ...
    </project>
Ravi K
  • 916
  • 6
  • 9
  • @RaviK- Which dependency need to put in tag? My project has only one dependency artifact - jnetpcap, group - jnetpcap, version - 1.4.r1425-1d. What I need to change can you please explain in detail. – ketan Jul 21 '17 at 04:55
  • Can you try adding jnetpcap dependency inside plugin in dependencies > dependency section. When you run java program through exec plugin, all necessary dependencies better to be given within plugin. With limited information in question, this is my calculated guess. – Ravi K Jul 21 '17 at 05:07
  • @RaviK- Yes I tried it has no affect. It didn't get libjnetpcap.so file so it is showing exception. I tried with providing -Djava.library.path option also. – ketan Jul 21 '17 at 05:40
  • Can you also make sure that your maven command is also using exact same java version as that of your IDE. Maven will generally take JAVA_HOME variable value. Give correct java to maven & then try your -Djava.library.path option along with it. – Ravi K Jul 21 '17 at 06:42
  • @RaviK- In my system only java 1.8 version is available and command line and eclipse both are using same 1.8 version only. I check maven also uses same java 1.8 (JAVA_HOME). – ketan Jul 21 '17 at 07:07
1

JnetPcap requires you to reference two libraries in your project:

  1. The JAR file containing the Java interfaces you can use from your code (jnetpcap.jar)
  2. The native library that exposes OS specific functions to the Java library (i.e., libjnetpcap.so or jnetpcap.dll)

The exception that you are seeing indicates that you are missing #2 at runtime. In this case, you have two options to make the library available to your application:

You can find out which directories are on your path on Ubuntu by echoing the $PATH system variable:

> echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin

Simply copy the native library into a directory that is already included on the system path.

Alternatively, you can pass the location of the library using the java.library.path argument to Java. Assuming the library is in a directory called lib inside your maven project directory, use the following configuration:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.2.1</version>
    <configuration>
        <executable>java</executable>
        <arguments>
            <argument>-Djava.library.path=${project.basedir}/lib</argument>
            <argument>-classpath</argument>
            <classpath />
            <argument>com.example.Main</argument>
        </arguments>
    </configuration>
 </plugin>

To execute this, simply run:

mvn exec:exec
Ben Damer
  • 906
  • 7
  • 13
  • @BenDamer- Thanks for your answer. My issue because of version conflict of jar and dependency. Any way your solution is very helpful. why maven dependency of version 1.3.0 is not available? why we need to provide jar externally? – ketan Jul 26 '17 at 08:50
  • Version 1.3.0 is getting fairly old by now, but 1.4.x is available in the Maven repository. Or you can always just install 1.3.0 manually into your repository. – Ben Damer Jul 26 '17 at 15:19
  • Hi @BenDamer, It's working good. I created maven like you answered. Now I want to add one more main class in this project without losing this structure. – ketan Jul 31 '17 at 11:12
  • Please mark my answer as accepted in that case. I would recommend that you create a new question for what you are trying to do next. – Ben Damer Jul 31 '17 at 15:31