Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven bundle plugin - How to add main class

I have a Maven project mjbean which has only one dependency: TestA. Here is the pom.xml for mjbean:

<groupId>com.mbean</groupId>
<artifactId>mjbean</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>bundle</packaging>

<build>
  <defaultGoal>install</defaultGoal>
  <plugins>
    <plugin>
      <groupId>org.apache.felix</groupId>
      <artifactId>maven-bundle-plugin</artifactId>
      <extensions>true</extensions>
      <configuration>
        <instructions>
          <Main-Class>com.mbean.Main</Main-Class>
          <Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
          <Embed-Transitive>true</Embed-Transitive>
          <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
          <Import-Package>*</Import-Package>
        </instructions>
      </configuration>
    </plugin>
  </plugins>
</build>

<name>mjbean</name>
<url>http://maven.apache.org</url>

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>3.8.1</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>com.testa</groupId>
    <artifactId>TestA</artifactId>
    <version>1.0.0-SNAPSHOT</version>
  </dependency>
</dependencies>

The main class is very easy:

package com.mbean;
import com.testa.Testcl;
public class Main {

public static void main(String[] args) {

    Testcl tcl = new Testcl();
    tcl.testmethod();
    }
}

I have specified the main class <Main-Class>com.mbean.Main</Main-Class> in maven-bundle-plugin. It runs good with Eclipse. Then I use Eclipse to generate the target bundle in the target folder. When I try to run it in command line: java -jar mjbean-0.0.1-SNAPSHOT.jar, I got this error:

Exception in thread "main" java.lang.NoClassDefFoundError: com/testa/Testcl
at com.mbean.Main.main(Main.java:12)
Caused by: java.lang.ClassNotFoundException: com.testa.Testcl
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)

Can anyone help me with this?

like image 775
Li' Avatar asked Mar 11 '13 22:03

Li'


2 Answers

The accepted answer isn't correct, the maven-bundle-plugin does support any manifest headers. It doesn't matter if the headers are part of the OSGI specification or not.

Manifest headers - Any instruction that starts with a capital letter will appear in the resulting bundle's manifest file; the value for the header will either be copied, augmented, or generated by BND depending on the instruction.

The configuration in the question is correct.

<configuration>
    <instructions>
        <Main-Class>com.mbean.Main</Main-Class>
    </instructions>
</configuration>

I guess the issue could have been that a wrong jar got loaded (there can be multiple jar files by other plugins) or maybe there was some built or caching issue and the jar file was not up to date.

like image 58
kapex Avatar answered Sep 20 '22 18:09

kapex


Main-Class isn't part of the OSGi bundle standard, and I don't believe that maven-bundle-plugin recognizes it.

You can follow the instructions for using an existing MANIFEST.MF file and add the instruction

<_include>src/main/resources/META-INF/MANIFEST.MF</_include>

and then include your Main-Class directive in that file. This is a little clunky, which may suggest that you're using the wrong tool for the job. If you just need an executable jar file, there are other Maven plugins that might be more suitable, like the maven-jar-plugin.

like image 38
Nathaniel Waisbrot Avatar answered Sep 20 '22 18:09

Nathaniel Waisbrot