You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2019/12/03 10:45:34 UTC
[camel] 01/02: CAMEL-14215: Adding camel-main-osgi.
This is an automated email from the ASF dual-hosted git repository.
acosentino pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git
commit b5a0b1d13180c2f1bc24c41c210036c4ac784fd9
Author: Bob Paulin <bo...@bobpaulin.com>
AuthorDate: Mon Dec 2 19:07:12 2019 -0600
CAMEL-14215: Adding camel-main-osgi.
---
apache-camel/pom.xml | 4 +
apache-camel/src/main/descriptors/common-bin.xml | 1 +
core/camel-main-osgi/pom.xml | 182 +++++++++++++++++++++
core/camel-main-osgi/src/assembly/test-bundles.xml | 37 +++++
.../camel/core/osgi/main/internal/Activator.java | 115 +++++++++++++
.../apache/camel/core/osgi/main/it/BundleIT.java | 120 ++++++++++++++
.../camel/core/osgi/main/it/PaxExamOptions.java | 70 ++++++++
core/pom.xml | 1 +
parent/pom.xml | 5 +
.../karaf/features/src/main/resources/features.xml | 1 +
10 files changed, 536 insertions(+)
diff --git a/apache-camel/pom.xml b/apache-camel/pom.xml
index 7556626..70fd984 100644
--- a/apache-camel/pom.xml
+++ b/apache-camel/pom.xml
@@ -107,6 +107,10 @@
<groupId>org.apache.camel</groupId>
<artifactId>camel-main</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-main-osgi</artifactId>
+ </dependency>
<!-- NOTE: auto-generated list of components when building camel catalog -->
<!-- camel components: START -->
diff --git a/apache-camel/src/main/descriptors/common-bin.xml b/apache-camel/src/main/descriptors/common-bin.xml
index 1b1db70..eb29501 100644
--- a/apache-camel/src/main/descriptors/common-bin.xml
+++ b/apache-camel/src/main/descriptors/common-bin.xml
@@ -40,6 +40,7 @@
<include>org.apache.camel:camel-cloud</include>
<include>org.apache.camel:camel-jaxp</include>
<include>org.apache.camel:camel-main</include>
+ <include>org.apache.camel:camel-main-osgi</include>
<!-- NOTE: auto-generated list of components when building camel catalog -->
<!-- camel components: START -->
diff --git a/core/camel-main-osgi/pom.xml b/core/camel-main-osgi/pom.xml
new file mode 100644
index 0000000..52a89da
--- /dev/null
+++ b/core/camel-main-osgi/pom.xml
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<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>
+
+ <parent>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>core</artifactId>
+ <version>3.1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>camel-main-osgi</artifactId>
+ <packaging>jar</packaging>
+
+ <name>Camel :: Main OSGi</name>
+ <description>Camel Main OSGi</description>
+
+ <properties>
+ <maven.failsafe.version>2.22.1</maven.failsafe.version>
+ <camel.osgi.activator>org.apache.camel.core.osgi.main.internal.Activator</camel.osgi.activator>
+ <camel.osgi.dynamic>*</camel.osgi.dynamic>
+ </properties>
+
+ <dependencies>
+ <!-- osgi -->
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>osgi.cmpn</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-core-osgi</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <!-- test -->
+
+ <!-- PAX Exam -->
+ <dependency>
+ <groupId>org.ops4j.pax.exam</groupId>
+ <artifactId>pax-exam</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.ops4j.pax.exam</groupId>
+ <artifactId>pax-exam-spi</artifactId>
+ <version>${pax-exam-version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.ops4j.pax.exam</groupId>
+ <artifactId>pax-exam-junit4</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.ops4j.pax.exam</groupId>
+ <artifactId>pax-exam-container-karaf</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.ops4j.pax.url</groupId>
+ <artifactId>pax-url-aether</artifactId>
+ <version>2.4.5</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.ops4j.pax.tinybundles</groupId>
+ <artifactId>tinybundles</artifactId>
+ <version>2.1.1</version>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- Karaf & Command Shell -->
+ <dependency>
+ <groupId>org.apache.karaf</groupId>
+ <artifactId>apache-karaf</artifactId>
+ <version>${karaf4-version}</version>
+ <type>zip</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.karaf.features</groupId>
+ <artifactId>framework</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <!-- Karaf Features -->
+ <dependency>
+ <groupId>org.apache.camel.karaf</groupId>
+ <artifactId>apache-camel</artifactId>
+ <version>${project.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ <version>1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.servicemix.tooling</groupId>
+ <artifactId>depends-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>generate-depends-file</id>
+ <goals>
+ <goal>generate-depends-file</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>pre-integration-test</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <descriptors>
+ <descriptor>src/assembly/test-bundles.xml</descriptor>
+ </descriptors>
+ <finalName>test</finalName>
+ <attach>false</attach>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <!-- Execute in the integration-test phase so that the packaged JAR
+ can be used -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>integration-test</phase>
+ <goals>
+ <goal>test</goal>
+ </goals>
+ <configuration>
+ <includes>
+ <include>**/*IT.java</include>
+ </includes>
+ <forkedProcessTimeoutInSeconds>300</forkedProcessTimeoutInSeconds>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/core/camel-main-osgi/src/assembly/test-bundles.xml b/core/camel-main-osgi/src/assembly/test-bundles.xml
new file mode 100644
index 0000000..0350be6
--- /dev/null
+++ b/core/camel-main-osgi/src/assembly/test-bundles.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+ <id>bundles</id>
+ <formats>
+ <format>dir</format>
+ </formats>
+ <includeBaseDirectory>false</includeBaseDirectory>
+ <dependencySets>
+ <dependencySet>
+ <outputDirectory/>
+ <outputFileNameMapping>${artifact.artifactId}.jar</outputFileNameMapping>
+ <includes>
+ <include>org.apache.camel:camel-main-osgi</include>
+ </includes>
+ </dependencySet>
+ </dependencySets>
+</assembly>
\ No newline at end of file
diff --git a/core/camel-main-osgi/src/main/java/org/apache/camel/core/osgi/main/internal/Activator.java b/core/camel-main-osgi/src/main/java/org/apache/camel/core/osgi/main/internal/Activator.java
new file mode 100644
index 0000000..719cbf2
--- /dev/null
+++ b/core/camel-main-osgi/src/main/java/org/apache/camel/core/osgi/main/internal/Activator.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.core.osgi.main.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.core.osgi.OsgiDefaultCamelContext;
+import org.apache.camel.model.ModelCamelContext;
+import org.apache.camel.model.RouteDefinition;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Activator implements BundleActivator, ServiceTrackerCustomizer<RouteBuilder, RouteBuilder> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Activator.class);
+ private ServiceRegistration<CamelContext> camelContextRef;
+ private ModelCamelContext camelContext;
+ private BundleContext bundleContext;
+ private ServiceTracker<RouteBuilder, RouteBuilder> routeServiceTracker;
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void start(BundleContext context) throws Exception {
+ this.bundleContext = context;
+ this.camelContext = new OsgiDefaultCamelContext(context);
+
+ this.routeServiceTracker = new ServiceTracker<RouteBuilder, RouteBuilder>(context, RouteBuilder.class, this);
+
+ camelContext.start();
+
+ camelContextRef = context.registerService(CamelContext.class, camelContext, null);
+
+ ServiceReference<RouteBuilder>[] existingRouteBuildersReferences = (ServiceReference<RouteBuilder>[]) context
+ .getAllServiceReferences(RouteBuilder.class.getName(), null);
+
+ if (existingRouteBuildersReferences != null) {
+ for (ServiceReference<RouteBuilder> currentRouteBuilderReference : existingRouteBuildersReferences) {
+ addingService(currentRouteBuilderReference);
+ }
+ }
+
+ this.routeServiceTracker.open();
+ LOG.info("Camel Main Osgi RouteBuilder ServiceTracker Tracker Open");
+ }
+
+ @Override
+ public RouteBuilder addingService(ServiceReference<RouteBuilder> reference) {
+ RouteBuilder builder = this.bundleContext.getService(reference);
+ try {
+ // need to synchronize here since adding routes is not synchronized
+ synchronized (camelContext) {
+ this.camelContext.addRoutes(builder);
+ LOG.debug("Camel Routes from RouteBuilder Class {} Added to Camel Main", builder.getClass().getName());
+ }
+ } catch (Exception e) {
+ LOG.error("Error Adding Camel Route Builder", e);
+ }
+
+ return builder;
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ this.routeServiceTracker.close();
+ camelContext.stop();
+ camelContext.removeRouteDefinitions(new ArrayList<RouteDefinition>(this.camelContext.getRouteDefinitions()));
+
+ context.ungetService(camelContextRef.getReference());
+ }
+
+ @Override
+ public void modifiedService(ServiceReference<RouteBuilder> reference, RouteBuilder service) {
+ removedService(reference, service);
+ addingService(reference);
+ }
+
+ @Override
+ public void removedService(ServiceReference<RouteBuilder> reference, RouteBuilder service) {
+ List<RouteDefinition> routesToBeRemoved = service.getRouteCollection().getRoutes();
+ try {
+ synchronized (camelContext) {
+ camelContext.removeRouteDefinitions(routesToBeRemoved);
+ LOG.debug("Camel Routes from RouteBuilder Class {} Removed to Camel Main",
+ service.getClass().getName());
+ }
+ } catch (Exception e) {
+ LOG.error("Error Removing Camel Route Builder", e);
+ }
+
+ }
+
+}
diff --git a/core/camel-main-osgi/src/test/java/org/apache/camel/core/osgi/main/it/BundleIT.java b/core/camel-main-osgi/src/test/java/org/apache/camel/core/osgi/main/it/BundleIT.java
new file mode 100644
index 0000000..35df365
--- /dev/null
+++ b/core/camel-main-osgi/src/test/java/org/apache/camel/core/osgi/main/it/BundleIT.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.core.osgi.main.it;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.ops4j.pax.exam.CoreOptions.junitBundles;
+import static org.ops4j.pax.exam.CoreOptions.streamBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class BundleIT {
+ @Inject
+ private BundleContext bc;
+
+ @Configuration
+ public Option[] configuration() throws IOException, URISyntaxException, ClassNotFoundException {
+ return options(
+ PaxExamOptions.KARAF.option(),
+ PaxExamOptions.CAMEL_CORE_OSGI.option(),
+ streamBundle(
+ TinyBundles.bundle()
+ .read(
+ Files.newInputStream(
+ Paths.get("target/test-bundles")
+ .resolve("camel-main-osgi.jar")))
+ .build()),
+ junitBundles());
+ }
+
+ @Test
+ public void testBundleLoaded() throws Exception {
+ boolean hasCore = false;
+ boolean hasOsgi = false;
+ boolean hasCamelMainOsgi = false;
+ for (Bundle b : bc.getBundles()) {
+ if ("org.apache.camel.camel-core".equals(b.getSymbolicName())) {
+ hasCore = true;
+ assertEquals("Camel Core not activated", Bundle.ACTIVE, b.getState());
+ }
+ if ("org.apache.camel.camel-core-osgi".equals(b.getSymbolicName())) {
+ hasOsgi = true;
+ assertEquals("Camel Core OSGi not activated", Bundle.ACTIVE, b.getState());
+ }
+
+ if ("org.apache.camel.camel-main-osgi".equals(b.getSymbolicName())) {
+ hasCamelMainOsgi = true;
+ assertEquals("Camel Main OSGi not activated", Bundle.ACTIVE, b.getState());
+ }
+ }
+ assertTrue("Camel Core bundle not found", hasCore);
+ assertTrue("Camel Core OSGi bundle not found", hasOsgi);
+ assertTrue("Camel Main OSGi bundle not found", hasCamelMainOsgi);
+ }
+
+ @Test
+ public void testRouteLoadAndRemoved() throws Exception {
+ CountDownLatch latch = new CountDownLatch(1);
+ ServiceRegistration<RouteBuilder> testServiceRegistration = bc.registerService(RouteBuilder.class,
+ new RouteBuilder() {
+
+ @Override
+ public void configure() throws Exception {
+ from("timer:test?fixedRate=true&period=300").process(exchange -> {
+ latch.countDown();
+ });
+ }
+ }, null);
+
+ latch.await(10, TimeUnit.SECONDS);
+
+ CamelContext camelContext = bc.getService(bc.getServiceReference(CamelContext.class));
+
+ assertEquals("There should be one route in the context.", 1, camelContext.getRoutes().size());
+
+ testServiceRegistration.unregister();
+
+ assertEquals("There should be no routes in the context.", 0, camelContext.getRoutes().size());
+
+ }
+
+}
diff --git a/core/camel-main-osgi/src/test/java/org/apache/camel/core/osgi/main/it/PaxExamOptions.java b/core/camel-main-osgi/src/test/java/org/apache/camel/core/osgi/main/it/PaxExamOptions.java
new file mode 100644
index 0000000..15284c4
--- /dev/null
+++ b/core/camel-main-osgi/src/test/java/org/apache/camel/core/osgi/main/it/PaxExamOptions.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.core.osgi.main.it;
+
+import java.io.File;
+
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.karaf.options.LogLevelOption;
+import org.ops4j.pax.exam.options.DefaultCompositeOption;
+
+import static org.ops4j.pax.exam.CoreOptions.maven;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.logLevel;
+
+public enum PaxExamOptions {
+ KARAF(
+ karafDistributionConfiguration()
+ .frameworkUrl(
+ maven()
+ .groupId("org.apache.karaf")
+ .artifactId("apache-karaf")
+ .versionAsInProject()
+ .type("zip"))
+ .name("Apache Karaf")
+ .useDeployFolder(false)
+ .unpackDirectory(new File("target/paxexam/unpack/")),
+ keepRuntimeFolder(),
+ // Don't bother with local console output as it just ends up cluttering the logs
+ configureConsole().ignoreLocalConsole(),
+ // Force the log level to INFO so we have more details during the test. It defaults to WARN.
+ logLevel(LogLevelOption.LogLevel.INFO)
+ ),
+ CAMEL_CORE_OSGI(
+ features(
+ maven()
+ .groupId("org.apache.camel.karaf")
+ .artifactId("apache-camel")
+ .type("xml")
+ .classifier("features")
+ .versionAsInProject(),
+ "camel-core", "camel-core-osgi")
+ );
+
+ private final Option[] options;
+
+ PaxExamOptions(Option... options) {
+ this.options = options;
+ }
+
+ public Option option() {
+ return new DefaultCompositeOption(options);
+ }
+}
diff --git a/core/pom.xml b/core/pom.xml
index 25db9fd..334e535 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -50,6 +50,7 @@
<module>camel-core-xml</module>
<module>camel-cloud</module>
<module>camel-main</module>
+ <module>camel-main-osgi</module>
</modules>
<build>
diff --git a/parent/pom.xml b/parent/pom.xml
index 790967a..f301399 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -810,6 +810,11 @@
<artifactId>camel-main</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-main-osgi</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<!-- NOTE: auto-generated list of components when building camel catalog -->
<!-- camel components: START -->
diff --git a/platforms/karaf/features/src/main/resources/features.xml b/platforms/karaf/features/src/main/resources/features.xml
index ff2448f..5b7d2ac 100644
--- a/platforms/karaf/features/src/main/resources/features.xml
+++ b/platforms/karaf/features/src/main/resources/features.xml
@@ -61,6 +61,7 @@
<bundle>mvn:org.apache.camel/camel-cloud/${project.version}</bundle>
<bundle>mvn:org.apache.camel/camel-jaxp/${project.version}</bundle>
<bundle>mvn:org.apache.camel/camel-main/${project.version}</bundle>
+ <bundle>mvn:org.apache.camel/camel-main-osgi/${project.version}</bundle>
<bundle>mvn:org.apache.camel/camel-caffeine-lrucache/${project.version}</bundle>
<!-- core components -->
<bundle>mvn:org.apache.camel/camel-bean/${project.version}</bundle>