Maven + Tycho, adding Maven dependencies
Asked Answered
L

3

11

We have an Eclipse Plugin which we build using Maven and Tycho. Currently however, we still provide all project dependencies through a bunch of manually added JAR files and not by Maven. This is due to the following reasons: (1) The dependencies are not available through a standard Eclipse update site (at least not in a current version), (2) the dependencies are not available as bundles.

The biggest part of these dependencies are the Selenium libraries (API, Remote, browser-specific libs and their transitive dependencies, such as Guava, etc.)

I've wasted hours, trying to pull those dependencies during our Maven build. Following this SO question, I tried the p2-maven-plugin, created an update site with our dependencies which I added to my Eclipse target platform. However, during runtime, classes, which are referenced across different JARs could not be loaded (I assume, from my very limited OSGi knowledge, because some necessary information was missing in the MANIFEST.MF files). Here's an example of the issue, when trying to create a RemoteWebDriver, which uses the DesiredCapabilities class (both classes in different bundles):

Exception in thread "Thread-8" java.lang.NoClassDefFoundError: org/openqa/selenium/remote/DesiredCapabilities
    at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:243)
    at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:126)
    at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:153)
    …
Caused by: java.lang.ClassNotFoundException: org.openqa.selenium.remote.DesiredCapabilities cannot be found by org.seleniumhq.selenium.remote-driver_2.45.0
    at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:439)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:352)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:344)
    at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:160)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 7 more

Is there anything I still need to take care of, when using the p2-maven-plugin? The relevant parts of the pom.xml looked like this:

<plugin>
    <groupId>org.reficio</groupId>
    <artifactId>p2-maven-plugin</artifactId>
    <version>1.1.1-SNAPSHOT</version>
    <executions>
        <execution>
            <id>default-cli</id>
            <configuration>
                <artifacts>
                    <artifact>
                        <id>org.seleniumhq.selenium:selenium-remote-driver:2.45.0</id>
                    </artifact>
                </artifacts>
            </configuration>
        </execution>
    </executions>
</plugin>
Lighting answered 25/12, 2015 at 18:33 Comment(1)
Might be you were not able to resolve those dependencies, because the p2 plugin simply acts as a Target Platform? During runtime those artifacts were not present.Decompound
L
15

Couldn't get it to work, so we're now using the maven-dependency-plugin with the copy-dependencies, which we execute during the Maven initialize phase to pull all necessary dependencies (contrary to my initial feeling, this can be combined with the pom.xml using the eclipse-plugin packaging and the "manifest first" approach). The relevant part looks like this:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.10</version>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>initialize</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <includeScope>runtime</includeScope>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

The Maven dependencies are then copied to target/dependency.

Only little issue: The Bundle-ClassPath in the MANIFEST.MF needs to be manually updated in case the name of a JAR file changes when updating Maven dependencies (e.g. commons-io-2.4.jar becomes commons-io-2.5.jar).

[edit] Revisiting this answer in regards to the last sentence above: The version numbers can be conveniently stripped through the following option: <stripVersion>true</stripVersion>. This means, the above library will be renamed to commons-io.jar and thus no paths need to be updated when a version number changes.

Lighting answered 29/12, 2015 at 12:21 Comment(5)
Thanks for that. but i don't know if all transitive dependencies which going with the maven dependency ".jar" need to be filtered or not for inclusion in p2 site.Swizzle
FYI: In the meantime, I had to further modularize corresponding project. So I had to go the extremely frustrating path and transform the non-OSGi dependencies to OSGi bundles using the maven-jar-plugin. This task was extreeemly tedious, causing me more than a weekend of work. Biggest issue: Lots of errors only show up during application startup or even during runtime of the application, when required packages cannot be found (this is the "better" kind of issue), or worse: classes cannot be found or are not compatible between packages.Lighting
In our case, the bundles created with the maven-jar-plugin contain all transitive dependencies, with some exceptions (JARs for API, big shared libs such as Guava, ...). Determining, which package to exclude, is mostly motivated by the issue described above (class incompatibilities at interacting bundles), or by economic factors (do not include fat transitivities in every bundle). The most optimal way would be, to have OSGI compatible bundle dependencies for each and every (transitive) dependencies. But this is very obviously not the case in reality. @SwizzleLighting
Thanks for clarification @Lighting , i have a similar problem here with transitive dependencies and tycho : #41214428Swizzle
This is a really interesting answer @Lighting - I also noted you might be able to change the folder it downloads to to the more convention (for Eclipse plugin purposes!) /lib using the <outputDirectory> configuration propertyHypocorism
T
0

Another possibility:

Some jar files may be broken (if you're using Eclipse, it's commonplace hibernate-commons-annotations-4.0.1.Final.jar; invalid LOC header (bad signature)? ). To check this possibility, try manually opening the jar to see if it's okay.

Trifoliate answered 12/3, 2017 at 14:30 Comment(0)
C
0

I also build an Eclipse plugin with Maven and Tycho. I have the same problem: the bundle org.eclipse.team.svn.core and org.eclipse.team.svn.ui are not available through a standard Eclipse update site.

Maybe you can try this to solve this kind of problem:

  1. In Dependencies, find the box Automated Management of Dependencies.
  2. Add the wanted plugin using Add...
  3. Choose Analyze code and add dependencies to the MANIFEST.MF via: Import-Package
  4. Click on Add Dependencies so that you find required packages in the box Imported Packages nearby.

Then you can run the Maven build.

Control answered 7/7, 2017 at 11:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.