5

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?

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
Li'
  • 3,133
  • 10
  • 34
  • 51

3 Answers3

4

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.

kapex
  • 28,903
  • 6
  • 107
  • 121
1

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.

Nathaniel Waisbrot
  • 23,261
  • 7
  • 71
  • 99
  • Can maven-jar-plugin work together with bundle-plugin? Is it possible to use jar-plugin to specify main class and bundle-plugin to generate the bundle at the same time? – Li' Mar 12 '13 at 18:35
  • @Li' No, the only way I see to specify a main class *and* use bundle-plugin is to provide your own manifest for it to modify. – Nathaniel Waisbrot Mar 12 '13 at 20:04
  • 1
    I have done another test. I use both bundle-plugin and maven-assembly-plugin in the pom.xml. But I did not use in bundle-plugin. Then maven install creates two file: 1 bundle without any dependencies and 1 jar file with all dependency included. So it is impossible to let bundle-plugin and assembly-plugin work together to create a bundle with all dependencies, right? – Li' Mar 12 '13 at 20:30
  • @Li' Right. They both have the job of creating a jar file. bundle-plugin is for OSGi specifically, so if you want to do something beyond OSGi (like Main-Class) you have to kludge a little. maven-assembly, maven-jar, and some others make jars for other circumstances (like when you want to build an executable jar). – Nathaniel Waisbrot Mar 12 '13 at 20:57
  • Here is another experiment. I use bundle-plugin with to create a bundle with all dependencies included. When I check the manifest, I am wondering why there are still many import-packages since all dependencies have been already included. Then I deploy this bundle to osgi container, I got error: missing export packages for these import packages. – Li' Mar 12 '13 at 22:42
  • @Li' I'm not sure of the answer to that. I think that this new question is distinct from what you've asked here and could be posted as a new question. That would give you room to nicely format the relevant excerpt of your POM and manifest. – Nathaniel Waisbrot Mar 13 '13 at 15:06
0

add the following to the maven-bundle-plugin section in your pom...

   ...
    <configuration>
      <archive>
        <manifest>
           <mainClass>your.main.Main</mainClass>
        </manifest>
      </archive>
      ...

Regards Roland

Roland
  • 169
  • 2
  • 4