I'm trying to build a Blueprint bundle to run in Apache Felix. I tried to make it running but I didn't succeed.
The blueprint bundle works fine in Karaf but not in Felix. Is it any documentation or a running example on the web to explain how to run a Blueprint bundle only with plain Felix. I suppose I have to manually add Aries to Felix platform but it didn't seem to work.
To be more precise, I want a simple service to see that it's loaded from a blueprint.xml XML config file as a Blueprint bundle. The service may have only one dummy method or even just a constructor with a println in it. That service class I want to refer it in OSGI-INF/blueprint/blueprint.xml so it will be loaded when the Blueprint bundle is loaded by Felix.
After spending some time trying to solve this problem I found the solution. So, you need the following bundles to be installed into your Felix (tested with v.4.4.1) in order to make Aries Blueprint running:
org.apache.aries.blueprint : org.apache.aries.blueprint : 1.1.0
org.apache.aries : org.apache.aries.util : 1.1.0
org.apache.aries.proxy : org.apache.aries.proxy : 1.0.1
org.apache.felix : org.apache.felix.configadmin : 1.8.0
one implementation of SLF4J (in this case will be PAX Logging):
org.ops4j.pax.logging : pax-logging-api : 1.4
org.ops4j.pax.logging : pax-logging-service : 1.4 (you may exclude log4j : log4j because is not needed)
These jars will enable Aries Blueprint in Felix (but only the XML configuration version). If you want to use annotations, you have to add also annotation related Jars.
Here is a pom to ease your work. Just run it and all the jar needed to be installed in felix will be in your target folder.
<?xml version="1.0" encoding="UTF-8"?>
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.aries</groupId>
<artifactId>blueprint-felix-assembly</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Blueprint Felix Jar Assembly</name>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<pax.logging.version>1.4</pax.logging.version>
<aries.version>1.1.0</aries.version>
<aries.proxy.version>1.0.1</aries.proxy.version>
<felix.config.admin.version>1.8.0</felix.config.admin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.configadmin</artifactId>
<version>${felix.config.admin.version}</version>
</dependency>
<dependency>
<groupId>org.ops4j.pax.logging</groupId>
<artifactId>pax-logging-api</artifactId>
<version>${pax.logging.version}</version>
</dependency>
<dependency>
<groupId>org.ops4j.pax.logging</groupId>
<artifactId>pax-logging-service</artifactId>
<version>${pax.logging.version}</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
<artifactId>org.apache.aries.blueprint</artifactId>
<version>${aries.version}</version>
</dependency>
<dependency>
<groupId>org.apache.aries</groupId>
<artifactId>org.apache.aries.util</artifactId>
<version>${aries.version}</version>
</dependency>
<dependency>
<groupId>org.apache.aries.proxy</groupId>
<artifactId>org.apache.aries.proxy</artifactId>
<version>${aries.proxy.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<excludeTransitive>true</excludeTransitive>
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Aries should run very well on Apache Felix it does not require Apache Karaf to run. In fact we are using plain equinox for our integration tests.
You can take a look at the integration test base class to see which bundles you need.
Related
I need to modify and deploy some liferay modules that I didn't write. The original developer is not with the company anymore and there's almost no documentation on the code. The project is structured differently to the liferay projects I'm familiar with, so I'm struggling with the deployment.
It's a maven project with a number of modules, and when I build it generates multiple jar files. When I copy one of those jar files to my local deployment folder Liferay prints something like:
13:07:23,201 INFO [com.liferay.portal.kernel.deploy.auto.AutoDeployScanner][ModuleAutoDeployListener:70] Module for /Users/ali/LIFERAY/liferay-portal-6.2-ee-sp14/deploy/com.monator.ehp.routes.servicemix.moci-1.6.1.jar copied successfully. Deployment will start in a few seconds.
... and then nothing. If I check the liferay/data/osgi/modules/ directory I do see the jar file is present there, however when I test the behaviour I do not see my changes reflected, even after restarting the tomcat server.
We're running Liferay 6.2 ee sp14 with tomcat and postgres. I believe the modules in question are osgi modules, but I don't think that changes the deployment method?
EDIT: This is the main project pom file, running "mvn install" in the same directory does not create a war file, but does create multiple individual jar files in the various child module folders:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.monator.tools</groupId>
<artifactId>monator-parent</artifactId>
<version>0.7.0</version>
</parent>
<groupId>com.monator.clients.moh</groupId>
<artifactId>camel-routes</artifactId>
<version>1.6.1</version>
<packaging>pom</packaging>
<name>Camel Route Project Parent</name>
<scm>
<url>https://bitbucket.org/monator/ehealth-portal-camel-routes.git</url>
<connection>scm:git:ssh://git#bitbucket.org/monator/ehealth-portal-camel-routes.git</connection>
<developerConnection>scm:git:ssh://git#bitbucket.org/monator/ehealth-portal-camel-routes.git</developerConnection>
</scm>
<modules>
<module>servicemix.routes.parent</module>
<module>liferay.routes.parent</module>
</modules>
<properties>
<camel.version>2.13.2</camel.version>
<osgi.export.package></osgi.export.package>
<osgi.import.package>*</osgi.import.package>
<osgi.bundle.symbolic.name>${project.groupId}.${project.artifactId}</osgi.bundle.symbolic.name>
</properties>
<build>
<finalName>${osgi.bundle.symbolic.name}-${project.version}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.4.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${osgi.bundle.symbolic.name}</Bundle-SymbolicName>
<Export-Package>${osgi.export.package}</Export-Package>
<Import-Package>${osgi.import.package}</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<!-- Dependencies only declared for IDE support -->
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-blueprint</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
<artifactId>org.apache.aries.blueprint.cm</artifactId>
<version>1.0.5</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-osgi</artifactId>
<version>5.10.0</version>
<!-- Since we're using Maven 3, this is necessary. -->
<exclusions>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>```
Liferay 6.x can deploy war files, not jars!
Maybe your maven projects builds many jars for then build a war file?
Better if you post the pom.xml and the internet crew try to understand the mistery..
EDIT:
This project build osgi jars for Apache Camel to create some custom routes! https://camel.apache.org/ , there are not Liferay modules!
(Maybe Liferay plays as Camel consumer/producer?)
I have a problem building the spring boot application. We need to build the project with the 'lib/bin/conf' structure using the maven. I did it with another project and there is no problem. But now, a conflict occurred and an action is recommended.
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
org.springframework.context.support.GenericApplicationContext.setApplicationStartup(GenericApplicationContext.java:165)
The following method did not exist:
'void org.springframework.beans.factory.support.DefaultListableBeanFactory.setApplicationStartup(org.springframework.core.metrics.ApplicationStartup)'
The method's class, org.springframework.beans.factory.support.DefaultListableBeanFactory, is available from the following locations:
jar:file:/target/OrderManager/libs/communication-latest.jar!/org/springframework/beans/factory/support/DefaultListableBeanFactory.class
jar:file:target/OrderManager/libs/spring-beans-5.3.8.jar!/org/springframework/beans/factory/support/DefaultListableBeanFactory.class
The class hierarchy was loaded from the following locations:
org.springframework.beans.factory.support.DefaultListableBeanFactory: file:target/OrderManager/libs/communication-latest.jar
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory: file:target/OrderManager/libs/communication-latest.jar
org.springframework.beans.factory.support.AbstractBeanFactory: file:target/OrderManager/libs/communication-latest.jar
org.springframework.beans.factory.support.FactoryBeanRegistrySupport: file:target/OrderManager/libs/communication-latest.jar
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry: file:target/OrderManager/libs/communication-latest.jar
org.springframework.core.SimpleAliasRegistry: file:target/OrderManager/libs/communication-latest.jar
Action:
Correct the classpath of your application so that it contains a single, compatible version of org.springframework.beans.factory.support.DefaultListableBeanFactory
How can I solve this problem? I'm using a lib named communication that is provided by our company.
This is my pom file.
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.artifact</groupId>
<artifactId>ordermanager</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Order Manager Component</name>
<properties>
<java.version>11</java.version>
<spring-cloud.version>Hoxton.SR7</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.4.2</version>
</dependency>
<dependency>
<groupId>com.excample.myArtifact</groupId>
<artifactId>communication</artifactId>
<version>latest</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>2.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
<configuration>
<assembleDirectory>target/OrderManager</assembleDirectory>
<repositoryName>libs</repositoryName>
<configurationDirectory>conf</configurationDirectory>
<configurationSourceDirectory>src/main/resources</configurationSourceDirectory>
<copyConfigurationDirectory>true</copyConfigurationDirectory>
<repositoryLayout>flat</repositoryLayout>
<useWildcardClassPath>true</useWildcardClassPath>
<programs>
<program>
<mainClass>com.example.artifact.ordermanager.OrderManagerComponentApplication</mainClass>
<id>OrderManager</id>
</program>
</programs>
</configuration>
</plugin>
</plugins>
</build>
</project>
the answer is already there:
Correct the classpath of your application so that it contains a single, compatible version of org.springframework.beans.factory.support.DefaultListableBeanFactory
Your problem is, that you've got 2 JAR files containing the same class org.springframework.beans.factory.support.DefaultListableBeanFactory. These are:
/target/OrderManager/libs/communication-latest.jar
target/OrderManager/libs/spring-beans-5.3.8.jar
You have to remove one of them. Now I don't know your project and architecture, but if you're using a company customized spring library, then you should remove the standard spring jar. Use maven's exclude mechanism for that, it is a so called transient dependency, so you didn't define it explicitly, but one of the dependencies you defined is dependending on that.
First you have to find out which dependency brings that spring-beans dependency in. Use maven's dependency tree to do that:
mvn dependency:tree
You can also use dependency analysis or read about the whole dependency management.
If you want to kick out the communication-latest.jar you should just remove the following in your pom.xml:
<dependency>
<groupId>com.excample.myArtifact</groupId>
<artifactId>communication</artifactId>
<version>latest</version>
</dependency>
For resolving this conflict you can use excludes-dependencies https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html
In this case, it should be
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
from
<groupId>com.excample.myArtifact</groupId>
<artifactId>communication</artifactId>
The problem was with version mismatching with the spring boot that is used in the communication library rather than the spring boot of the main project. So, I changed the spring boot version to 2.3.3.RELEASE and the problem are solved.
Some friends told me to exclude the spring-beans artifact. I did not do that and version changing was enough, But testing the approaches that are told on this topic, can be useful.
Is there any way to specify complete folder path of the jars to be pushed on driver as well as executor like --jars in spark-submit, which excepts comma separated jar names with full path. But it's tedious work if we do have too many jars to be pushed on both driver as well as executor.
Question : Is there a way to specify to push complete jar folder on both driver
and executors?
Yes you can make uber jar which is self contained distribution with all depedencies packed inside.
sample if you are using maven, you can use maven shade plugin or assembly plugin for this. below is shade example.
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.maventest</groupId>
<artifactId>mytest</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>mytest</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<finalName>uber-${artifactId}-${version}</finalName>
</configuration>
</plugin>
</plugins>
</build>
</project>
If you are using sbt see this
your spark submit will look like ....
spark-submit [PATH_TO_YOUR_UBER_JAR]/[YOUR_UBER_JAR].jar
Further reading for example Googles article : Managing Java dependencies for Apache Spark applications
Running spark on yarn you have to be able to set spark.yarn.archive or spark.yarn.jars in spark-defaults.conf configuration file.
spark.yarn.archive is intended for distribution of the archive with all the jars you need on your executors.
spark.yarn.jars is for separate jars.
You may find more information in the official docs.
I have a maven multi module project designed like the first answer in following SO post:
Multi-module maven with Spring Boot
Now I want a common maven module that can contain some models to be used by multiple microservices. If I make this common project as a child of the first level parent pom (so that all dependencies injected by boot like jpa, jackson etc are available to common), then STS/Spring is detecting it as a boot application and complains about no Main class on maven build.
Can someone suggest how I can achieve this?
Current Code:
parent pom.xml: (Only relevant parts included)
<project>
<name>...</name>
<groupId>...</groupId>
<artifactId>...</artifactId>
<packaging>pom</packaging>
<version>...</version>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Brixton.M3</version>
<relativePath />
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
child (common module) pom.xml (only relevant parts), not to be boot app:
<project>
<artifactId>...</artifactId>
<version>...</version>
<name>...</name>
<parent>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
</parent>
</project>
I don't have all the details regarding your project but my best guess is that the spring-boot-maven-plugin is defined on the parent (or you are using the spring-boot-starter-parent in your root pom). This effectively ask the build to package your module as a Spring Boot app (which is not what you want).
STS probably looks for that hint to figure out if a module contains a Spring Boot application or not. Maybe it would be nicer if it looks for a main class annotated with #EnableAutoConfiguration (or SpringBootApplication).
You can fix the problem easily (from the build side) by specifying the skip property of the repackage goal
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
If STS still picks up the module as a Spring Boot app, I'd create an issue in their tracker
Normally, Spring Boot won't start a web container if it's not present in the module.
I would suggest you to analyse your dendencies using the command
mvn dependency:tree
One more brute-force way of ensuring is use this configuration in your application.properties
spring.main.web-environment=false
Here are two ways to fix this:
You can add the skip property like #Stephane Nicoll mentioned. However, this will completely ignore the test cases inside that module. https://docs.spring.io/spring-boot/docs/current/maven-plugin/examples/it-skip.html
Another option is to add a classifier property to make a separate executable jar out of this module. https://docs.spring.io/spring-boot/docs/current/maven-plugin/examples/repackage-classifier.html
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
This fix will make sure the dependent module get its required jar and the source module will still be an executable one.
I have a Spring Boot web application that I cannot start when using the executable jar directly.
I am using Spring Boot 1.2.0.RELEASE, Maven 3.0.5, Java 1.7.0_72.
I have a requirement to use the hp-roman8 character set - in order to handle incoming requests from some remote legacy systems. To provide the hp-roman8 charset I use net.freeutils.jcharset in version 1.5.
The jcharset artifact is installed in my local repository
However when launching my application using java -jar the application fails to start and I get "java.nio.charset.UnsupportedCharsetException: hp-roman8" as cause.
The same error occurs if I do mvn spring-boot:run unless I configure spring-boot-maven-plugin to always fork.
With <fork>true</fork> spring-boot:run starts the application successfully and the hp-roman8 charset is available on the classpath.
However <fork>true</fork> has no effect on the created jar, so I am still unable to launch my application using java -jar - and continue to get the "java.nio.charset.UnsupportedCharsetException: hp-roman8".
The jcharset-1.5.jar is included correctly in the created executable jar file next to the rest of the dependencies in the path "lib/jcharset-1.5.jar" so I don't quite understand why it is not available on the classpath when launching the jar.
Have any of you seen similar behavior, or have any ideas as to what I could try out in order to troubleshoot or even resolve this problem?
update:
I have also tried changing the main-class to use the PropertiesLauncher instead (using the <layout>ZIP</layout> tag in the plugin configuration) - see http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#build-tool-plugins-maven-packaging.
Afterwards I added loader.path to my application.properties. Even if I specify the absolute path to jcharset-1.5.jar I still get the UnsupportedCharsetException.
I also tried using an exploded archive but still no go.
You could use Maven's shade plugin rather than Spring Boot's Maven plugin. The main difference is that the shade plugin takes all of your project's dependencies and packages them directly in the jar file, i.e. it doesn't use nested jars. While this has some disadvantages, it does mean that a single class loader is used to load all of your application's classes and, therefore, JCharset is available to the application class loader.
When you're using the Shade plugin, you shouldn't use Spring Boot's starter parent. You may want to import Boot's dependency management instead.
Your pom would look something like this:
<?xml version="1.0" encoding="UTF-8"?>
<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>org.springframework.boot</groupId>
<artifactId>spring-boot-sample-jcharset</artifactId>
<version>0.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-boot-sample-jcharset</name>
<description>Spring Boot sample showing the use of JCharset in an executable jar</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.7</java.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.2.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Any additional dependencies, including JCharset -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>sample.jcharset.SampleJCharsetApplication</Main-Class>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>