Maven POM Configuration
This section describes the configuration of pom.xml. Please refer to the source for full details.
Artifact packaging
<groupId>com.logpresso.sonar</groupId>
<artifactId>logpresso-sample-app</artifactId>
<version>1.1.2608.0</version>
<packaging>bundle</packaging>
<name>Logpresso Sample App</name>
Always specify the group ID of your Logpresso app as com.logpresso.sonar. We recommend defining the artifact ID in the form logpresso-VENDOR-MODEL. The version is defined in the form Major.Minor.YYMM.REV. This is because it is easier to estimate the compatible Logpresso platforms if the app version indicates when it was deployed.
Finally, it's important to note that the packaging is specified as bundle. The maven-bundle-plugin plugin, described below, does the bundle packaging.
Properties
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<jdk.version>11</jdk.version>
<app.code>sample</app.code>
<node.version>v20.18.0</node.version>
<npm.version>10.9.0</npm.version>
</properties>
Specify the file encoding as UTF-8 so that the operating system locale does not affect the build, and specify the JDK version as 11. The jdk.version variable is used below.
The last three variables are needed only if you develop an XDR UI. They pin the app code and the Node.js and npm versions used for the frontend build. Pinning the versions keeps builds from differing because developers installed different tool versions.
Maven repositories
<repositories>
<repository>
<id>logpresso-repo</id>
<name>Logpresso Maven Repository</name>
<url>https://maven.logpresso.com/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>logpresso-plugin-repo</id>
<name>Logpresso Maven Repository</name>
<url>https://maven.logpresso.com/</url>
</pluginRepository>
</pluginRepositories>
Logpresso provides the libraries needed for third-party development in the https://maven.logpresso.com repository. Add the <pluginRepository> setting to download the iPOJO plugin needed for bytecode manipulation during the build phase, and the <repository> setting to download the app API and iPOJO library.
Compiler options
Specify the source code and bytecode versions, whether to include debug information, and whether to show deprecation warnings when compiling Java.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<encoding>UTF-8</encoding>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<debug>true</debug>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
The maven-bundle-plugin plugin creates an OSGi bundle by adding an OSGi manifest to a JAR file. An OSGi bundle is a JAR file with an OSGi manifest appended to the META-INF/MANIFEST.MF file.
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>5.1.4</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>com.logpresso.sonar.sample</Bundle-SymbolicName>
<Export-Package>
com.logpresso.sonar.sample;version=${project.version},
</Export-Package>
<Import-Package>
org.json;version="1.1.0",
org.araqne.codec;version="2.2",
org.araqne.log.api;version="3.13.0",
org.logpresso.api.profile;version="1.1.0",
org.logpresso.api.profile.query;version="1.1.0",
org.araqne.logdb;version="3.10.0",
org.araqne.msgbus;version="1.12.0",
org.araqne.msgbus.handler;version="1.12.0",
org.araqne.msgbus.rest;version="1.12.0",
com.logpresso.sonar.api.*;resolution:=optional,
*
</Import-Package>
<Private-Package>
com.logpresso.sonar.sample.impl,
com.logpresso.sonar.sample.msgbus,
com.logpresso.sonar.sample.query,
</Private-Package>
</instructions>
</configuration>
</plugin>
You need to look at the four items in <instruction>:
Bundle-SymbolicName: Defines the bundle identifier. Write it according to Java package naming conventions.Export-Package: Enter a list of packages to be exposed to other OSGi bundles. Typically, you would only expose packages that contain Java interfaces. Use the${project.version}macro to specify the version of the package you are releasing.Import-Package: Enter a list of packages to import from another OSGi bundle. Specify the minimum version by defining;version="VERSION"after the package name. If you don't specify a version, the build plugin uses the version of the maven artifact defined in<dependencies>, so the range of compatible package versions may not be as wide as intended and bundle dependencies may not be resolved.Private-Package: Enter a list of internal packages that you do not want to make public to other OSGi bundles. Typically, packages containing implementations should not be made public; only interfaces should be made public externally, so that implementation details can be easily changed at any time.
The Import-Package predefines the versions of the packages required for the Logpresso app API calls. The set of package versions that can be imported may change depending on the sonar-app-api library version (currently 5.0.2603.0).
The org.araqne.msgbus.handler and org.araqne.msgbus.rest packages are needed when you develop a REST API plugin. Omit them if the app serves no data to a screen.
There is a constraint on the maven-bundle-plugin version. 5.1.5 and later are not compatible with Logpresso, so use 5.1.4. Later versions fail the build at the bundle step. See bnd issue 2507 for the details.
Take care with what you put in Export-Package. Never re-export a package that sonar-app-api provides. That library is a copy of the platform's packages meant for compile time only. Export one from your app and another bundle can be wired to your app's copy instead of the platform's during OSGi dependency resolution, at which point identically named classes are treated as different types and calls into platform services fail. Exporting packages the app defines itself is fine.
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-ipojo-plugin</artifactId>
<version>1.12.1.asm8</version>
<executions>
<execution>
<goals>
<goal>ipojo-bundle</goal>
</goals>
</execution>
</executions>
</plugin>
iPOJO is a framework that makes it possible to develop OSGi components declaratively. Because OSGi assumes runtime plugins, features that each bundle depends on can be installed or removed at any time. This makes developing using only the OSGi interface very complicated to implement, as you need to be notified of every state change, cascading to disable or enable features. iPOJO enables you to develop OSGi services declaratively by defining a component lifecycle model and adding simple annotations.
iPOJO manipulator recognizes iPOJO annotations during the build phase and performs the automatic conversion by inserting the bytecode. Therefore, maven-ipojo-plugin must be called during the build phase as shown above.
Frontend build
This section applies only if you develop an XDR UI.
frontend-maven-plugin downloads Node.js and npm into the project directory and runs the frontend build.
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.15.0</version>
<configuration>
<workingDirectory>src/main/ui</workingDirectory>
<nodeVersion>${node.version}</nodeVersion>
<npmVersion>${npm.version}</npmVersion>
</configuration>
<executions>
<execution>
<id>install-node-npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<phase>generate-resources</phase>
</execution>
<execution>
<id>npm-install</id>
<goals>
<goal>npm</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<id>npm-build</id>
<goals>
<goal>npm</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
</executions>
</plugin>
Note that all three executions bind to the generate-resources phase. The frontend build writes its output into the src/main/resources/WEB-INF directory, and process-resources then copies src/main/resources into the bundle. Bind the frontend build to a later phase and the files you just produced never make it into the bundle, so the screen does not appear after you install the app.
maven-antrun-plugin copies the bundle JAR to an app file.
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<copy file="${project.build.directory}/${project.build.finalName}.jar"
tofile="${project.build.directory}/${project.artifactId}-${project.version}.app" />
</target>
</configuration>
</execution>
</executions>
</plugin>
An app file is not a separate format — it is the bundle JAR copied with a different extension. You use it when you install the app in the web console.
Declare this plugin after maven-bundle-plugin and maven-ipojo-plugin. All three bind to the package phase, and executions in the same phase run in declaration order. Declare it earlier and you copy a JAR that iPOJO has not instrumented yet, so the components do not work once installed.
Dependencies
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.ipojo.annotations</artifactId>
<version>1.12.1.asm8</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>com.logpresso.sonar</groupId>
<artifactId>sonar-app-api</artifactId>
<version>5.0.2603.0</version>
</dependency>
</dependencies>
The Logpresso app uses the following libraries:
junit: Used for writing unit tests. Unit test classes are placed under thesrc/test/javadirectory.org.apache.felix.ipojo.annotations: Provides iPOJO component annotations.slf4j-api: Provides logging interface. Logs are written to thelog/araqne.logfile, and the log level can be adjusted at runtime.sonar-app-api: Provides the Logpresso app API. The version of this library refers to the compatible Logpresso platform version.