简体   繁体   中英

adding external jars with bundles to project only in Eclipse

Is there a way to add external jars with bundles without editting the target platform and just defining these jars for the current project. I run into some errors having wrong plugins defined globally.

As reference I used this answer: External jars not resolved as bundles in MANIFEST.MF

I once tried to use the target platform to do that. But eclipse PDE is very messy and strange.

Today I use Maven Bundle Plugin to manage my OSGi projects. Unless you really need to work with eclipse plugins/platform and you have no other choice, I would suggest you to try maven with the felix maven bundle plugin ( http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html ).

The way I do it is by creating one master project with bundles inside. Here's how to create such project from scratch:

在此处输入图片说明

First, in Eclipse Kepler (or later), create a new maven project, by going File->New->Maven Project. In the new window that shows up, choose the folder to save the project into, it can be your workspace or any other folder.

在此处输入图片说明

Select the option “Create simple project (skip achetype selection)”, and press Next. Fill the group id name and artifact id name. These are parameters used to identify your project in maven repositories, where each project is represented by the pair (don't ask me why did they choose this way to name projects). You can name them anything you want. I just appended “.master” to my artifact id to highlight that this project is just a parent POM. The parent POM is a POM.XML file containing all the information that is common to all our bundles we want to develop.

在此处输入图片说明

Press Finish. Now if you look at your POM.XML you'll see very few lines with some useless information and our group and artifact ids.

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>such.osgi.example</groupId>
 <artifactId>very.example.master</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 </project>

We need to make maven understand that we are going to create bundles, using felix apache maven bundle plugin. More specifically your POM.XML must look like this:

        <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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <modelVersion>4.0.0</modelVersion>
          <groupId>such.osgi.example</groupId>
          <artifactId>very.example.master</artifactId>
          <version>0.0.1-SNAPSHOT</version>
          <name>${project.artifactId}</name>

            <properties>
                <project.build.sourceEncoding>ISO-8859-1</project.build.sourceEncoding>
            </properties>

            <packaging>pom</packaging>

            <modules>
            </modules>

            <profiles>
                <!-- http://www.lucamasini.net/Home/osgi-with-felix/creating-osgi-bundles-of-your-maven-dependencies -->
                <!-- -Pcreate-osgi-bundles-from-dependencies bundle:wrap -->
                <profile>
                    <id>create-osgi-bundles-from-dependencies</id>
                    <build>
                        <directory>${basedir}/bundles</directory>
                        <plugins>
                            <plugin>
                                <groupId>org.apache.felix</groupId>
                                <artifactId>maven-bundle-plugin</artifactId>
                                <version>2.0.1</version>
                                <extensions>true</extensions>
                                <executions>
                                    <execution>
                                        <id>wrap-my-dependency</id>
                                        <goals>
                                            <goal>wrap</goal>
                                        </goals>
                                        <configuration>
                                            <wrapImportPackage>;</wrapImportPackage>
                                        </configuration>
                                    </execution>
                                </executions>
                            </plugin>
                        </plugins>
                    </build>
                </profile>
            </profiles>

            <build>
                <sourceDirectory>src</sourceDirectory>
                <testSourceDirectory>test</testSourceDirectory>

                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-compiler-plugin</artifactId>
                        <version>3.1</version>
                        <configuration>
                            <source>1.6</source>
                            <target>1.6</target>
                        </configuration>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.felix</groupId>
                        <artifactId>maven-bundle-plugin</artifactId>
                        <version>2.3.7</version>
                        <extensions>true</extensions>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-javadoc-plugin</artifactId>
                        <version>2.5</version>
                    </plugin>
                </plugins>
            </build>

            <dependencies>
                <dependency>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                    <version>4.8.1</version>
                </dependency>
                <dependency>
                    <groupId>org.apache.felix</groupId>
                    <artifactId>org.osgi.core</artifactId>
                    <version>1.4.0</version>
                </dependency>
                <dependency>
                    <groupId>org.apache.felix</groupId>
                    <artifactId>org.osgi.compendium</artifactId>
                    <version>1.4.0</version>
                </dependency>
            </dependencies>
        </project>

If you look at the dependencies part you'll see that all our bundles will need junit, org.osgi.core and org.osgi.compendium (I choose felix implementations because equinox is as much as a pain in the ass as Eclipse PDE, unless used outside the eclipse environment, but that's a different story…). By default maven will search these dependencies in maven's central repository, a huge repository online that has tons of java libraries at our disposal. If you now select the project in the project explorer window and right-click on it and go to Run As->Maven Install you'll see the console outputting this:

                SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
                SLF4J: Defaulting to no-operation (NOP) logger implementation
                SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
                [INFO] Scanning for projects...
                [INFO]                                                                         
                [INFO] ------------------------------------------------------------------------
                [INFO] Building very.example.master 0.0.1-SNAPSHOT
                [INFO] ------------------------------------------------------------------------
                [INFO] 
                [INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ very.example.master ---
                [debug] execute contextualize
                [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is p
                latform dependent!
                [INFO] Copying 0 resource
                [INFO] 
                [INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ very.example.master ---
                [INFO] Nothing to compile - all classes are up to date
                [INFO] 
                [INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ very.example.mast
                er ---
                [debug] execute contextualize
                [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is p
                latform dependent!
                [INFO] Copying 0 resource
                [INFO] 
                [INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ very.example.master 
                ---
                [INFO] Nothing to compile - all classes are up to date
                [INFO] 
                [INFO] --- maven-surefire-plugin:2.10:test (default-test) @ very.example.master ---
                [INFO] Surefire report directory: C:\Users\Pedro\workspace\very.example.master\target\surefire-
                reports
                Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-junit3/2.10
                /surefire-junit3-2.10.pom
                Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-junit3/2.10/
                surefire-junit3-2.10.pom (2 KB at 4.5 KB/sec)
                Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-junit3/2.10
                /surefire-junit3-2.10.jar
                Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-junit3/2.10/
                surefire-junit3-2.10.jar (26 KB at 143.4 KB/sec)

                -------------------------------------------------------
                 T E S T S
                -------------------------------------------------------

                Results :

                Tests run: 0, Failures: 0, Errors: 0, Skipped: 0

                [INFO] 
                [INFO] --- maven-jar-plugin:2.3.2:jar (default-jar) @ very.example.master ---
                [INFO] Building jar: C:\Users\Pedro\workspace\very.example.master\target\very.example.master-0.
                0.1-SNAPSHOT.jar
                [INFO] 
                [INFO] --- maven-install-plugin:2.3.1:install (default-install) @ very.example.master ---
                [INFO] Installing C:\Users\Pedro\workspace\very.example.master\target\very.example.master-0.0.1
                -SNAPSHOT.jar to C:\Users\Pedro\.m2\repository\such\osgi\example\very.example.master\0.0.1-SNAP
                SHOT\very.example.master-0.0.1-SNAPSHOT.jar
                [INFO] Installing C:\Users\Pedro\workspace\very.example.master\pom.xml to C:\Users\Pedro\.m2\re
                pository\such\osgi\example\very.example.master\0.0.1-SNAPSHOT\very.example.master-0.0.1-SNAPSHO
                T.pom
                [INFO] ------------------------------------------------------------------------
                [INFO] BUILD SUCCESS
                [INFO] ------------------------------------------------------------------------
                [INFO] Total time: 2.711s
                [INFO] Finished at: Mon May 19 14:47:00 BST 2014
                [INFO] Final Memory: 5M/15M
                [INFO] ------------------------------------------------------------------------

Notice the BUILD SUCCESS part, that's very important, it means that everything is ok so far! Now, If you try Run As -> Maven Build… and type -Pcreate-osgi-bundles-from-dependencies bundle:wrap in the field “Goals” in the window that shows up, and hit Run, you'll make maven download those 3 dependencies (junit and org.orgi.*) and create bundles from them (this action is called wrapping as a bundle). It will put those bundles in the bundles/ directory of your project:

在此处输入图片说明

Don't worry if in your project you also see maven dependencies or other folders besides the ones I have here. Sometimes eclipse puts them there, sometimes it doesn't, it's like magic. If you ran into any strange problem just select the project and go to Maven -> Update Maven Project, select Force Update of Snapshots/Releases, ensure your project is selected in the list above and hit Ok.

在此处输入图片说明

Now its time to create our bundles. For the sake of simplicity we'll only create one simple bundle, so the easiest way to do it is to create a new folder inside our project and give it the name of our bundle, for example:

在此处输入图片说明

Now create a POM.XML file inside that folder with the following content:

    <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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>

        <parent>
            <relativePath>../pom.xml</relativePath>
            <groupId>such.osgi.example</groupId>
            <artifactId>very.example.master</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </parent>

        <artifactId>very.example.mybundles.helloworldbundle</artifactId>
        <packaging>bundle</packaging>

        <build>
            <sourceDirectory>src</sourceDirectory>
            <plugins>
                <plugin>
                    <groupId>org.apache.felix</groupId>
                    <artifactId>maven-bundle-plugin</artifactId>
                    <extensions>true</extensions>
                    <configuration>
                        <instructions>
                            <Bundle-SymbolicName>${project.artifactId};singleton:=true</Bundle-SymbolicName>
                            <Bundle-Version>${project.version}</Bundle-Version>
                            <Export-Package>very.example.mybundles.helloworldbundle</Export-Package>
                            <Bundle-Activator>very.example.mybundles.helloworldbundle.Activator</Bundle-Activator>
                        </instructions>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                </plugin>
            </plugins>
        </build>

        <name>${project.artifactid}</name>

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

        <dependencies>
            <dependency>
                <groupId>org.zeromq</groupId>
                <artifactId>zeromq-scala-binding_2.10</artifactId>
                <version>0.0.7</version>
            </dependency>
        </dependencies>
    </project>

In the very.example.master's POM.XML look for the tags and replace them with this:

    <modules>
        <module>very.example.mybundles.helloworldbundle</module>
    </modules>

Now in Eclipse you do File->Import->Existing Maven Projects and choose the folder of your master project, you'll see eclipse detecting the new project automatically.

在此处输入图片说明

Hit Finish and look for the new imported project. You'll see that your POM file contains errors, but they are false positives, just ignore them for now. What maven is trying to tell you is that you don't have any source files (namely a bundle activator) in you project. So create a new folder inside this new project called “src” and put your Activator.java inside. Its code is as follows:

    package very.example.mybundles.helloworldbundle;

    import org.osgi.framework.BundleActivator;
    import org.osgi.framework.BundleContext;

    public class Activator implements BundleActivator {

        @Override
        public void start(BundleContext arg0) throws Exception {
            System.out.println("hello world!");
        }

        @Override
        public void stop(BundleContext arg0) throws Exception {
            System.out.println("bye!");
        }

    }

Your project should have no errors by now, and it should run maven install perfectly! Each time you make maven install it will generate a .jar in your target/ folder. That .jar is your project's bundle that you can deploy to the OSGi Framework. But now you want to generate all the related dependencies as bundles too so that they can also go into the OSGi Framework runtime. For our example I've put a dependency in this bundle POM file, that has nothing to do with our actual code, it isn't needed, but I put it there to show you how maven would behave if you had dependencies for this bundle (others that java.lang, that are already included in any java runtime environment). Select the master project and go to Run As -> Maven Build… and type -Pcreate-osgi-bundles-from-dependencies bundle:wrap in the field “Goals” in the window that shows up, and hit Run, you'll make maven download those all dependencies from the parent/master project and its bundles (in our situation we just have one bundle) and create bundles from them. You now should have your bundles in the bundles/ folder inside each project (master and the helloworldbundle). Now download the felix OSGi Framework and copy all those jars, plus the jar file in your bundle's target/ directory to the felix framework bundle/ folder.

在此处输入图片说明

Note: Each time you run felix you can delete the cache folder to fully reset the framework, in case you update some bundles and updates corrupt the runtime. Now open cmd, go to your felix root path and type: java –jar bin\\felix.jar You should see a huge error message. This is because that example dependency we added in the bundle's pom file. So lets delete it since it was just an example. So you need to delete this:

    <dependencies>
            <dependency>
                <groupId>org.zeromq</groupId>
                <artifactId>zeromq-scala-binding_2.10</artifactId>
                <version>0.0.7</version>
            </dependency>
        </dependencies>

Do Run As -> Maven Install in eclipse, copy the new generated .jar in the target/ folder into felix framework again. Delete the org.zeromq.scala-binding_2.10_0.0.7.jar file from there and run felix framework again. You should now see the hello world message!

在此处输入图片说明

Hope this helps!

In this link you can find the project I've made for this example and the felix framework with this project deployed, ready to run as you see at the end of this mini tutorial.

https://www.dropbox.com/s/pazhtrjmu50zsv9/example-source.zip

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM