OSGI: generate bundle-classpath in maven-bundle-plugin - maven-2

I am trying to add all the jars from web-inf/lib into the Bundle-ClassPath.
I saw several ways to do it, none of them is working:
1) add
<Embed-Dependency>*;scope=compile|runtime;inline=true</Embed-Dependency>
<Embed-Directory>WEB-INF/lib</Embed-Directory>
<Embed-Transitive>true</Embed-Transitive>
2) add
<Bundle-ClassPath>.,{maven-dependencies},WEB-INF/classes</Bundle-ClassPath>
Of course, writing jars one-by-one in "Bundle-ClassPath" solves the problem, but it doesn't sound like a reasonable solution.
thanks

In your first code snippet, wouldn't using <Embed-Dependency> as you have it written work? The examples at http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html seem to indicate it would.
Also, what version of the bnd plugin are you using? These features are available as of 1.2.0+.

Working example for a classic webapp being OSGified
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
<configuration>
<instructions>
<Private-Package>org.example</Private-Package>
<Web-ContextPath>webappcontextpath</Web-ContextPath>
<Bundle-ClassPath>.,WEB-INF/classes,{maven-dependencies}</Bundle-ClassPath>
<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
<Embed-Directory>WEB-INF/lib</Embed-Directory>
</instructions>
<supportedProjectTypes>
<supportedProjectType>war</supportedProjectType>
</supportedProjectTypes>
</configuration>
</execution>
</executions>
</plugin>
Note that Embed-Dependency is inside the instructions element

Related

Compiling gRPC,with both Kotlin and Java using Maven (various packages not found)

I have a mixed kotlin/java project and I wanted to add gRPC to it. I configured the gRPC plugin as usual:
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>
com.google.protobuf:protoc:3.11.2:exe:${os.detected.classifier}
</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>
io.grpc:protoc-gen-grpc-java:1.25.0:exe:${os.detected.classifier}
</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
...
but when building from scratch
mvn clean && mvn package
the kotlin code would never find the generated sources. When building first from IntelliJ it would work fine - IntelliJ knows what to do.
I tried configuring build-helper-maven-plugin to include the generated-sources directories that the protobuf compiler and stub generator use, but that didn't seem to have any effect (and in fact seems unnecessary).
The answer it turns out is because of the order plugins execute. Generally for kotlin-java hybrid projects you want to compile the kotlin first so that the java compiler knows how to find kotlin classes. The problem is, if you do that the kotlin compiler doesn't see the protoc-generated java classes yet. It's a circular dependency.
It took me a while to figure it out, but to fix it you just have to tell the kotlin compiler where to find the protoc-generated sources like this:
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<goals> <goal>compile</goal> </goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/main/java</sourceDir>
<sourceDir>${project.build.directory}/generated-sources/protobuf/java/</sourceDir>
<sourceDir>${project.build.directory}/generated-sources/protobuf/grpc-java/</sourceDir>
</sourceDirs>
</configuration>
</execution>
...
</plugin>
It took me entirely too long to figure that out, so I'm posting this as a self-answered question to perhaps save somebody else some time.
I saw a number of related questions but none exactly the same. Good luck.

How do I Use the Local Maven Repository in IntelliJ

I want to use the local repo provided by IntelliJ to add several jar files to a Maven project, but I have no clue how. I tried to look at the guides on apache.org but they were extremely unclear to me.
What I gathered from the guides was that I had to put something like this in the pom.xml...
...
<build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>cb-1.12</id>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<file>F:\path\to\file.jar</file>
<groupId>agroup</groupId>
<artifactId>anartifact</artifactId>
<version>1.12</version>
</configuration>
</execution>
<execution>
<id>cb-1.11</id>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<file>F:\path\to\file.jar</file>
<groupId>agroup</groupId>
<artifactId>anartifact</artifactId>
<version>1.11</version>
</configuration>
</execution>
...the same thing several more times...
</executions>
</plugin>
</build>
...
I added that and tried adding the dependencies but IntelliJ was unable to resolve them. I tried running it anyway thinking maybe the plugin had to add them first and nothing happened except for the wall of errors about classes not being found. The local repo folder didn't have the new group either. I'm not sure what else to try.

buildnumber-maven-plugin and maven-assembly-plugin

I've set up the buildnumber-maven-plugin to pull the version number from SVN and stash it away in the META-INF/MANIFEST.MF inside the jar. That works ok.
But when I try to use it together with the maven-assembly-plugin to pack all the other libs together It doesn't seem to work, the version number stuff is not included in the manifest in the ...-jar-with-dependencies.jar.
Has anybody managed to get them to work together?
Alternatively: Is there a (reasonable simple) way to output the ${buildNumber} into a text file (.properties, perhaps) using Maven? An Ant task in Maven could do it I guess but is there an easier way?
Argh... after posting I found THIS: how to add arbitrary information in manifest from maven assembly plugin and smacked my head.
OK, so My maven-assembly-plugin bit in the pom now looks like this
<build> ... <plugins> ...
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>...</mainClass>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Implementation-Build>${buildNumber}</Implementation-Build>
</manifestEntries>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>

Maven annotation processing with maven-compiler-plugin

I try to compile my code that contains annotations that generate source code. I use the maven-compiler-plugin and build-helper-maven-plugin. My POM is looking like that:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<generatedSourcesDirectory>${project.build.directory}/generated-sources/apt</generatedSourcesDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/apt</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
When I run mvn compile, ${project.build.directory}/generated-sources/apt is added as a source directory, and the generated sources are generated in the correct directory. But I get compiler errors because of missing references to the generated classes. It's like the generated source directory is not included in the compilation process.
I also try apt-maven-plugin which does not generate anything. And maven-annotation-plugin but it behaves as describe above.
The release 2.0.7-SNAPSHOT of maven-annotation-plugin should solve the problem
fwiw I just downgraded from 3.0 to 2.5.1 and fixed an issue I was seeing with APT processing not being executed after a few runs, using maven so just downgraded one version:
http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.apache.maven.plugins%22%20AND%20a%3A%22maven-compiler-plugin%22
Can you try with the latest version of maven compiler plugin (2.3.2)?
Also build-helper-maven-plugin is not required since it looks like you are using the maven-compiler-plugin itself to generate the sources from the annotation.

How to remove duplicate content from pom.xml for Maven?

I ran into such a situation, when packaging a project using maven, I'd like both the source package and the binary package, and they have the same manifest.mf file. Then I have to write the same entry in both plugin configuration of maven-source-plugin and maven-jar-plugin, like this:
<plugins>
<plugin>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifestEntries>
<Artifiact>${project.name}</Artifiact>
<Version>${project.version}</Version>
<Vendor>${project.organization.name}</Vendor>
<Built-By>Shiva Wu</Built-By>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
<manifestEntries>
<Artifiact>${project.name}</Artifiact>
<Version>${project.version}</Version>
<Vendor>${project.organization.name}</Vendor>
<Built-By>Shiva Wu</Built-By>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
It's really not convenient to modify both of them while changing settings. Is there a better way to resolve this?
Thanks:)
There is no better way to handle it than what you are doing.
A couple extra things though. You can stick these configurations into a reuseable "corporate" or "standard" parent POM within the plugin management section and then you won't have to specify them again in any other pom. See here for details:
Best way to share portions of a Maven pom.xml across unrelated projects?
The other thing I notice is that your personal name should be substituted with a variable that should be set from within your settings.xml file. This will help increase build portability.