OSGi-bundles not activating when run by Tycho surefire - java

I have several OSGi bundles that are built in Eclipse using normal manifest-managed dependencies and external builds with Maven Tycho.
Running the bundles inside of Eclipse on Equinox works fine. Building them with Tycho works fine.
Now I want to use Tycho Surefire to run integration tests and for that I created a simple test bundle that contains some basic tests. The bundles under test rely on some other bundles present in the OSGi-container and some minor start level tweaks in order to run correctly - like I said, the bundles themself start up perfectly fine when running them normally on Equinox.
So to mimic that for Tycho Surefire, I specified the following in the pom.xml of the test bundle:
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-surefire-plugin</artifactId>
<version>0.21.0</version>
<configuration>
<bundleStartLevel>
<bundle>
<id>org.hibernate.osgi</id>
<level>6</level>
<autoStart>true</autoStart>
</bundle>
<!-- plus a few more bundles in the real pom.xml -->
</bundleStartLevel>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>target-platform-configuration</artifactId>
<configuration>
<dependency-resolution>
<extraRequirements>
<requirement>
<type>eclipse-plugin</type>
<id>org.hibernate.entitymanager</id>
<versionRange>4.2.12.Final</versionRange>
</requirement>
<requirement>
<type>eclipse-plugin</type>
<id>org.hibernate.osgi</id>
<versionRange>4.2.12.Final</versionRange>
</requirement>
<!-- plus a few more bundles in the real pom.xml -->
</extraRequirements>
</dependency-resolution>
</configuration>
</plugin>
</plugins>
</build>
Interestingly, the tests failed. After some research I found out how I can access the OSGi console during/after the failed test run to investigate the problem further (OSGi console after running tycho tests).
My findings are, that although all necessary bundles (all transitively derived bundles and all manually specified ones) are present in the OSGi-container only the ones with a distinctive <bundleStartLevel> have been started (plus the OSGi-core-bundles of course).
So given the above example, my findings are that while both org.hibernate.osgi and org.hibernate.entitymanager have been resolved, only the first is in the 'ACTIVE' state. This obviously messes up the whole startup and my guess is that the tests would run fine if the bundles would start up as expected.
When I look at a "normal" Eclipse-OSGi-Launch configuration, there is a parameter "Default Auto-Start" that is set to true by default. I did not find anything like that in the Tycho Surefire documentation, but is it possible that setting a specific start level for some bundles somehow overrides the auto start of other bundles? At least I wouldn't guess that Tycho isn't auto starting any bundles at all by default...
I'd appreciate any hints on how to investigate that issue further or any clues for how I can get Tycho to start my bundles without having to specify a distinct start level for each.

If anyone is still stumbling onto this:
Since Tycho 0.23 the bundle auto start is configurable.
<configuration>
<defaultStartLevel>
<level>7</level>
<autoStart>true</autoStart>
</defaultStartLevel>
</configuration>

Related

Installing local jar to automated pipeline and sonarqube: how to do it with no command and no systempath?

I am developing a project which needs a client personal jar, and it needs to be deployed on a pipeline of tools which are out of our control (sadly). One of the tools in this pipeline is sonarqube.
To build and deploy we have to use maven.
I put the jar into a folder of the project, and tried various way to actually make it work.
The first (working) way was to have it as a system with a systemPath to the folder of the project. It compiled, worked and everything, but sonarqube apparently hates systemPath and made us take it away.
After a tiny bit of searching, we added to our pom a maven-install-plugin, bounded an install-file to validate phase and configured to generate the dependency. This seems to work on local if I first run mvn validate and THEN mvn clean package. Otherwise, it tries to look for the jar on the main repository and fails. If I comment the tag and leave only the plugin active, I noticed it executes the plugin, installs the jar to local repository, but build fails due to not resolving packages and classes inside the jar. If I now put the tag in, everything works, because it now find the jar in the repository.
While this solution works, it doesnt suite me because the repository will be emptied every once in a while, and to restart everything I would need to commits, one knownligly failing, just to install the jar.
I tried addind a tag instead, pointing to a project dir where I would store the necessary jar, and that works just fine on my PC, but utterly fails on the pipeline, looking at main repository only (I guess it is some configuration on the pipeline, but cant really tell, being outside my control)
Was actually able to do it with maven install plugin,
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<configuration>
<groupId>com.exmaple.stuff</groupId>
<artifactId>ClientJar</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<file>${project.basedir}/src/main/resources/ClientJar-1.0.jar</file>
<generatePom>true</generatePom>
</configuration>
<executions>
<execution>
<id>install-client-jar</id>
<phase>validate</phase>
<goals>
<goal>install-file</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
And having dependency
<!-- Client jar -->
<dependency>
<groupId>example</groupId>
<artifactId>ClientJar</artifactId>
<version>1.0</version>
</dependency>
If you notice, the tricky part here was actually that groupId is different between the dependency and the plugin declaration. I do not know if this difference is due to the configuration of their artifactory server, but it seems to work locally too.
Also it is needed to explicitly run mvn validate in the pipeline

Intellij not recognising symbols in Maven POM

I'm working with a project that has, historically, been supported and developed in an Eclipse environment. I'm hoping to move this over to Intellij, and I'm currently using the full (Ultimate) package.
There are a few intricacies of the build process that don't appear to be working, which relate to selectively building the resources for the project. I could work around this, but would rather try and understand why IntelliJ and Eclipse are building the same project in a slightly different way.
I've noticed in my parent POM that the following code has an issue:
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.2</version>
<configuration>
<includes>
<include>**/*.js</include>
</includes>
<nosuffix>true</nosuffix>
</configuration>
</plugin>
Intellij is saying element includes is not allowed here' and itcannot resolve symbol 'include'`.
As far as I can see, the declarations are valid and in the correct place, and maven appears to be set up as required with the maven plugins installed as required too. The POM uses the http://maven.apache.org/maven-v4_0_0.xsd schema.
This kind of stuff has generally been left untouched for a number of years, but I can't see why it is having issues with this particular symbol/declaration?
As above, I've checked the plugins, Maven settings, all the usual suspects. Another of the plugins uses <excludes> with no errors, which makes it a bit more of a puzzle to me?
Can anyone help?

spring-boot-devtools reload of multi-module maven project changes

Reload of multi-module maven project changes
Setting
Imagine a multi-module maven-project. The project structure is:
pom.xml //parentpom
|
pom.xml //submodule_1
|
pom.xml //submodule_2
.
.
.
pom.xml //submodule_7
For example submodule_5 has submodule_6 and submodule_7 as dependencies. The submodule_5 can be build to construct a War-file which can be deployed. Spring-Boot-Devtools provide the feature of automatic-restart whenever there is a change to submodule_5 it's classpath.
Whenever the application is run using:
mvn spring-boot:run
And changes are made to submodule_5 (depending on which IDE you use the classpath get changed. (for Eclipse automaticaly / for InteliJ when pressing Ctrl+F9)) spring-boot automaticaly restarts the application and changes are added. Changes which happen to submodule_6 or submodule_7 don't trigger the automatic restart.
Questions
Is there a way to make it so that whenever you make changes in submodule_6 or submodule_7 to have them force a restart and there-for apply the changes?
Spring-boot-devtools uses two classloaders: "The Base Classloader" & "The Restart Classloader". Is it so that on initial start of the application submodule_6 and submodule_7 get added to "The Base Classloader" whilst submodle_5 is kept in the "The Restart Classloader"? Making it so that whenever submodule_5 forces a restart it uses the versions of submodule_6 and submodule_7 out of "The Base Classloader"?
You may specify additional folders to be watched by spring-boot-devtools, in application.properties:
spring.devtools.restart.additional-paths=../submodule_6,../submodule_7
See Spring's documentation on using-boot-devtools-restart-additional-paths.
To fix this problem I started running the application from within InteliJ. without having to add.
spring.devtools.restart.additional-paths=../submodule_6,../submodule_7
IntelliJ and spring-boot seem to work together very wel. The reason it was not working for me in the first place was because I was working from the commandline at first.
Difference between commandline and IDE
So spring-boot-devtools uses two classloaders to load an application. Jars will be loaded ones in the "Base classloader", your application will be loaded in the "restart classloader". This last classloader will restart everytime there is a change on the classpath.
Whenever running submodule_5 from the commandline, it will build the submodule_6 and submodule_7 and add the jars to the build of submodule_5. Whenever changes are made in submodule_6 and submodule_7 spring-boot won't even notice since it's only watching submodule_5 and has the jars it needs. Even if you would specifically tell it to also watch those submodules, it still won't rebuild those, it'll just keep using the jars it already has loaded in the "base classloader" (This is my assumption, I'm not 100% certain of the way it works).
Whenever running submodule_5 from the IDE, it won't create the jar of the submodule_6 and submodule_7. It will just use their classpath. This makes it so that changes in your intire project's classpath (all submodules) will trigger the automatic restart and the changes will be applied.
EXTRA
Whenever running from the IDE changes to resources like html-files, css-files, xml-files . . . won't trigger a restart since this is not a change in the classpath. But the changes will still be visible.
I tried with spring.devtools.restart.additional-paths and in any case it is useless : source change restart the application but helpless because the application doesn't have the target/classes of modules during its execution.
With spring-boot:run executed on quite recent IntelliJ versions : it works out of the box.
With spring-boot:run executed on command line : there are at least two cases.
Case 1) we want to execute spring-boot:run from the module that has the spring boot main class (submodule_5 in the op question).
We need to add in the plugin configuration of its pom.xml the additional classpaths of compiled classes that we want that spring-boot plugin be aware it :
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<folders>
<folder>
../submodule_6/target/classes
</folder>
<folder>
../submodule_7/target/classes
</folder>
</folders>
</configuration>
</plugin>
</plugins>
</build>
Case 2) we want to execute spring-boot:run from the parent-module.
It works only with pom multi-modules that are also parent of modules.
We need to do two changes :
First, add the spring boot plugin declaration with flag skip in the parent pom :
`<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>`
Then add in the pom.xml of the module that has the spring boot main class (submodule_5 in the op question) :
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
We can now start the application from the parent pom with :
mvn -pl submodule_5 -am spring-boot:run
FYI these maven flags specify to apply the goal on submodule_5 after applied that on its dependencies (whereas the skip flag in the multi/parent pom.xml).

How do I create an Eclipse plugin release using Maven and Tycho?

I am building an Eclipse project that consists of a number of plug-ins that are packed together. I have create POM files for each component and a main POM for the project. Something like this:
projectDir\releng\pom.xml <-- Parent project
projectDir\proj1\pom.xml <-- Child project 1
projectDir\proj2\pom.xml <-- Child project 2
My build currently works by calling the parent POM which builds everything. Until now I have been building using 0.0.1-SNAPSHOT as the version of the parent POM, and in each Eclipse plug-in I have 0.0.1.qualifier as the version in the MANIFEST.MF file.
I now want to promote my latest version to 0.1.0. From my understanding, this means that I have to go over ALL of my POM files AND MANIFEST.MF files and upgrade the version in both of them (since while the version is defined in the parent POM, it is referenced in all child POM:s).
Is this the correct way to do this or is there a way to automate the whole process and not make mistakes?
P.S. There is the Maven Release plugin but this won't work with Eclipse.
For the version update step of a relase process, there is the tycho-versions-plugin which knows how to consistently update the POMs and manifests.
Just go to the root of your parent/aggregator module and call
mvn org.eclipse.tycho:tycho-versions-plugin:set-version -DnewVersion="0.1.0"
This will update the version of the parent project and of all child projects with the same/equivalent version as the parent project. In your case, these are all projects because the Eclipse versions 0.0.1.qualifier is considerered equivalent to 0.0.1-SNAPSHOT in Tycho.
For the remaining steps of the release process (tagging, building, pushing tags, etc.) just call the appropriate SCM or Maven commands, e.g. from a script. I haven't tried to use the maven-release-plugin for this (and apparently no-one else has).
Please have a look here: Unleash Maven Plugin - Tycho Releases
The Unleash Maven Plugin is implemented as an alternative to the Maven Release Plugin and has a Tycho feature which should do exactly what you need. Furhtermore it is much more flexible, failure tolerant and has an integrated rollback feature.
I will publish some blog posts soon to promote and explain this plugin.
just some hints on how we implemented it.
It can be done with an extra plugin that does transformation of versions in MANIFEST.MF and *.product files. This plugin needs to be a lifecycle participant. #Component(role = AbstractMavenLifecycleParticipant.class) the reason for this is that is must transform and commit before the release plugin starts to look for modifications. Then it must also to transformation back after the release.
The mojo executor plugin saves a good deal of work since it can call the replacer, buildhelper and scm plugin from inside your plugin.
Another important gotcha is that you need to disable to hard coded clean invocation that tycho does by confguring the release plugin to configure the clean plugin to skip execution.
Hope this helps.
There is a new feature in tycho-1.1.0 (unreleased at the time of this post) that should support what you're trying to do.
If you've configured your pom correctly for standard maven-release + added the dep to tycho 1.1.0, you can customize your build as follows [1]:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<preparationGoals>org.eclipse.tycho:tycho-versions-plugin:${tycho-version}:update-eclipse-metadata org.apache.maven.plugins:maven-scm-plugin:1.9.5:add org.apache.maven.plugins:maven-scm-plugin:1.9.5:checkin</preparationGoals>
<completionGoals>org.eclipse.tycho:tycho-versions-plugin:${tycho-version}:update-eclipse-metadata org.apache.maven.plugins:maven-scm-plugin:1.9.5:add org.apache.maven.plugins:maven-scm-plugin:1.9.5:checkin</completionGoals>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-plugin</artifactId>
<executions>
<execution>
<id>default-cli</id>
<goals>
<goal>add</goal>
<goal>checkin</goal>
</goals>
<configuration>
<includes>**/META-INF/MANIFEST.MF, **/feature.xml, **/*.product</includes>
<excludes>**/target/**</excludes>
<message>Changing the Eclipse files versions</message>
</configuration>
</execution>
</executions>
</plugin>
[1] This is taken directly from a tutorial that describes this new feature:
https://wiki.eclipse.org/Tycho/Release_Workflow

PMD multiple rulesets pass build but single ruleset fails build

I am using PMD maven plugin for my project and I am seeing very strange behavior in it. The following pom.xml configuration fails the build with violations in basic.xml -
<configuration>
<rulesets>
<ruleset>${project.basedir}\ruleset\basic.xml</ruleset>
<!-- ruleset>${project.basedir}\ruleset\braces.xml</ruleset>
<ruleset>${project.basedir}\ruleset\design.xml</ruleset>
<ruleset>${project.basedir}\ruleset\controversial.xml</ruleset>
<ruleset>${project.basedir}\ruleset\coupling.xml</ruleset>
<ruleset>${project.basedir}\ruleset\clone.xml</ruleset>
<ruleset>${project.basedir}\ruleset\comments.xml</ruleset-->
</rulesets>
</configuration>
But the below one passes the build smoothly -
<configuration>
<rulesets>
<ruleset>${project.basedir}\ruleset\basic.xml</ruleset>
<ruleset>${project.basedir}\ruleset\braces.xml</ruleset>
<ruleset>${project.basedir}\ruleset\design.xml</ruleset>
<ruleset>${project.basedir}\ruleset\controversial.xml</ruleset>
<ruleset>${project.basedir}\ruleset\coupling.xml</ruleset>
<ruleset>${project.basedir}\ruleset\clone.xml</ruleset>
<ruleset>${project.basedir}\ruleset\comments.xml</ruleset>
</rulesets>
</configuration>
The build should have failed in the second scenario also. As per what I have noticed, if the last rule (in above example comments.xml) does not have any code violation then the build will not break even if any of the rulesets above it (basic.xml, braces.xml, etc.) have code violations. I am unable to understand the reason behind this behavior. Can someone help me out with this?
I found the issue. There was an issue with Maven Plugin version 3.3 . Now I am using version 3.1 and the exact same code is working as expected.

Categories