diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 13dc139794..50e04c8728 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -4,6 +4,38 @@ This page describes the noteworthy improvements provided by each release of Ecli
## 3.0.0 (under development)
+### new sisu-osgi-connect
+
+The new sisu-osgi-connect provides an implementation for plexus according to the [Connect Specification](http://docs.osgi.org/specification/osgi.core/8.0.0/framework.connect.html#framework.connect) that allows to run an embedded OSGi Framework from the classpath of a maven-plugin.
+As both, the maven plugin and the embedded framework, share the same classlaoder you can use the best of both worlds and interact seamless with them.
+
+This can be used in the following way:
+
+```
+@Component(role = MyPlexusComponent.class)
+public class MyPlexusComponent {
+ @Requirement(hint = "connect")
+ private EquinoxServiceFactory serviceFactory;
+
+ public void helloConnect() {
+ serviceFactory.getService(HelloWorldService.class).sayHello();
+ }
+}
+```
+
+For the setup you need to do the following:
+
+1. include any bundle you like to make up your plexus-osgi-connect framework as a dependency of your maven plugin
+2. include a file `META-INF/sisu-connect.bundles` that list all your bundles you like to have installed in the format `bsn[,true]`, where `bsn` is the symbolid name and optionally you can control if your bundle has to be started or not
+3. include the following additional dependency
+```
+
+ org.eclipse.tycho
+ sisu-osgi-connect
+ ${tycho-version}
+
+```
+
### Deprecated Features
The `tycho-compiler:compile` and `tycho-compiler:testCompile` option `requireJREPackageImports` is deprecated now and will produce a warning when used, bundles currently rely on this option should migrate to proper importing packages from the non java.* namespace.
diff --git a/p2-maven-plugin/pom.xml b/p2-maven-plugin/pom.xml
index 7c2518e33f..a97f9a23c6 100644
--- a/p2-maven-plugin/pom.xml
+++ b/p2-maven-plugin/pom.xml
@@ -72,9 +72,19 @@
1.4.100
- org.eclipse.platform
- org.eclipse.equinox.frameworkadmin
- 2.2.0
+ org.eclipse.platform
+ org.eclipse.equinox.frameworkadmin
+ 2.2.0
+
+
+ org.eclipse.platform
+ org.eclipse.equinox.preferences
+ 3.10.1
+
+
+ org.eclipse.platform
+ org.eclipse.equinox.security
+ 1.3.800
org.apache.maven
@@ -102,11 +112,110 @@
org.eclipse.equinox.p2.updatesite
1.2.300
+
org.eclipse.tycho
tycho-embedder-api
${project.version}
+
+ org.eclipse.tycho
+ sisu-osgi-api
+ ${project.version}
+
+
+ org.eclipse.tycho
+ sisu-osgi-connect
+ ${project.version}
+
+
+
+ org.eclipse.platform
+ org.eclipse.equinox.p2.jarprocessor
+ 1.2.300
+
+
+
+ org.eclipse.platform
+ org.eclipse.equinox.concurrent
+ 1.2.100
+
+
+ org.eclipse.platform
+ org.eclipse.equinox.simpleconfigurator
+ 1.4.0
+
+
+ org.eclipse.platform
+ org.eclipse.equinox.app
+ 1.6.100
+
+
+ org.eclipse.platform
+ org.eclipse.equinox.frameworkadmin.equinox
+ 1.2.200
+
+
+ org.eclipse.platform
+ org.eclipse.equinox.simpleconfigurator.manipulator
+ 2.2.0
+
+
+
+ org.eclipse.platform
+ org.eclipse.equinox.p2.transport.ecf
+ 1.3.300
+
+
+ org.eclipse.ecf
+ org.eclipse.ecf.identity
+ 3.9.402
+
+
+ org.eclipse.ecf
+ org.eclipse.ecf.provider.filetransfer
+ 3.2.800
+
+
+ org.eclipse.ecf
+ org.eclipse.ecf.filetransfer
+ 5.1.102
+
+
+ org.eclipse.ecf
+ org.eclipse.ecf
+ 3.10.0
+
+
+
+
+ org.apache.felix
+ org.apache.felix.scr
+ 2.2.2
+
+
+
+ org.osgi
+ org.osgi.service.component
+ 1.5.0
+
+
+
+ org.bouncycastle
+ bcpg-jdk15on
+ 1.70
+
+
+ org.bouncycastle
+ bcprov-jdk15on
+ 1.70
+
+
+ commons-io
+ commons-io
+ 2.11.0
+
+
diff --git a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/DefaultProvisioningAgent.java b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/DefaultProvisioningAgent.java
index e850a3ded6..57df2e5d4e 100644
--- a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/DefaultProvisioningAgent.java
+++ b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/DefaultProvisioningAgent.java
@@ -12,15 +12,11 @@
*******************************************************************************/
package org.eclipse.tycho.p2maven;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
-import org.eclipse.equinox.p2.core.spi.IAgentServiceFactory;
-import org.osgi.framework.BundleContext;
+import org.eclipse.sisu.equinox.EquinoxServiceFactory;
@Component(role = IProvisioningAgent.class)
public class DefaultProvisioningAgent implements IProvisioningAgent {
@@ -28,38 +24,27 @@ public class DefaultProvisioningAgent implements IProvisioningAgent {
@Requirement
private Logger log;
- @Requirement(hint = "plexus")
- private BundleContext bundleContext;
-
- @Requirement(role = IAgentServiceFactory.class)
- private Map factoryMap;
-
- private Map services = new ConcurrentHashMap();
+ @Requirement(hint = "connect")
+ private EquinoxServiceFactory serviceFactory;
@Override
public Object getService(String serviceName) {
- return services.computeIfAbsent(serviceName, role -> {
- IAgentServiceFactory serviceFactory = factoryMap.get(role);
- if (serviceFactory != null) {
- return serviceFactory.createService(DefaultProvisioningAgent.this);
- }
- return null;
- });
+ return serviceFactory.getService(IProvisioningAgent.class).getService(serviceName);
}
@Override
public void registerService(String serviceName, Object service) {
- throw new UnsupportedOperationException();
+ serviceFactory.getService(IProvisioningAgent.class).registerService(serviceName, service);
}
@Override
public void stop() {
-
+ throw new UnsupportedOperationException();
}
@Override
public void unregisterService(String serviceName, Object service) {
- throw new UnsupportedOperationException();
+ serviceFactory.getService(IProvisioningAgent.class).unregisterService(serviceName, service);
}
}
diff --git a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/InstallableUnitGenerator.java b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/InstallableUnitGenerator.java
index c50c93ffac..f3b5ea5262 100644
--- a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/InstallableUnitGenerator.java
+++ b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/InstallableUnitGenerator.java
@@ -41,10 +41,12 @@
import org.eclipse.equinox.internal.p2.publisher.eclipse.IProductDescriptor;
import org.eclipse.equinox.internal.p2.updatesite.CategoryParser;
import org.eclipse.equinox.internal.p2.updatesite.SiteModel;
+import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.publisher.IPublisherAction;
import org.eclipse.equinox.p2.publisher.eclipse.BundlesAction;
import org.eclipse.equinox.p2.publisher.eclipse.Feature;
+import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager;
import org.eclipse.tycho.PackagingType;
import org.eclipse.tycho.p2maven.actions.AuthoredIUAction;
import org.eclipse.tycho.p2maven.actions.CategoryDependenciesAction;
@@ -53,7 +55,6 @@
import org.eclipse.tycho.p2maven.actions.ProductFile2;
import org.eclipse.tycho.p2maven.helper.PluginRealmHelper;
import org.eclipse.tycho.p2maven.io.MetadataIO;
-import org.osgi.framework.BundleContext;
import org.xml.sax.SAXException;
/**
@@ -71,9 +72,8 @@ public class InstallableUnitGenerator {
private static final String KEY_UNITS = "InstallableUnitGenerator.units";
- // this requirement is here to bootstrap P2 service access
- @Requirement(hint = "plexus")
- private BundleContext bundleContext;
+ @Requirement
+ private IProvisioningAgent provisioningAgent;
@Requirement(role = InstallableUnitProvider.class)
private Map additionalUnitProviders;
@@ -97,6 +97,7 @@ public class InstallableUnitGenerator {
public Map> getInstallableUnits(Collection projects,
MavenSession session)
throws CoreException {
+ init();
Objects.requireNonNull(session);
List errors = new CopyOnWriteArrayList();
Map> result = new ConcurrentHashMap>();
@@ -120,6 +121,13 @@ public Map> getInstallableUnits(Colle
throw new CoreException(multiStatus);
}
+ private void init() {
+ // this requirement is here to bootstrap P2 service access
+ // see https://github.com/eclipse-equinox/p2/issues/100
+ // then this would not be required anymore
+ provisioningAgent.getService(IArtifactRepositoryManager.class);
+ }
+
/**
* Computes the {@link IInstallableUnit}s for the given project, the computation
* is cached unless forceUpdate is true
meaning data is always
@@ -136,6 +144,7 @@ public Map> getInstallableUnits(Colle
public Collection getInstallableUnits(MavenProject project, MavenSession session,
boolean forceUpdate)
throws CoreException {
+ init();
Objects.requireNonNull(session);
log.debug("Computing installable units for " + project + ", force update = " + forceUpdate);
synchronized (project) {
diff --git a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/PlexusBundleContext.java b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/PlexusBundleContext.java
deleted file mode 100644
index 8990a13d85..0000000000
--- a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/PlexusBundleContext.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2022 Christoph Läubrich and others.
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Christoph Läubrich - initial API and implementation
- *******************************************************************************/
-package org.eclipse.tycho.p2maven;
-
-import java.io.File;
-import java.io.InputStream;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.List;
-
-import org.codehaus.plexus.component.annotations.Component;
-import org.codehaus.plexus.component.annotations.Requirement;
-import org.codehaus.plexus.logging.Logger;
-import org.codehaus.plexus.personality.plexus.lifecycle.phase.Disposable;
-import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
-import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
-import org.eclipse.osgi.internal.framework.FilterImpl;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.BundleListener;
-import org.osgi.framework.Filter;
-import org.osgi.framework.FrameworkListener;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceObjects;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-//FIXME this should not be necessary at all see https://bugs.eclipse.org/bugs/show_bug.cgi?id=578387
-@Component(role = BundleContext.class, hint = "plexus")
-public class PlexusBundleContext implements BundleContext, Initializable, Disposable {
-
- @Requirement
- private Logger log;
-
- private List legacyActivators = List.of(
- // see https://github.com/eclipse-equinox/p2/issues/100
- new org.eclipse.pde.internal.publishing.Activator() //
- );
-
- @Override
- public String getProperty(String key) {
- return System.getProperty(key);
- }
-
- @Override
- public Bundle getBundle() {
- throw new IllegalStateException("this is not OSGi!");
- }
-
- @Override
- public Bundle installBundle(String location, InputStream input) throws BundleException {
- throw new BundleException("this context does not support installations");
- }
-
- @Override
- public Bundle installBundle(String location) throws BundleException {
- throw new BundleException("this context does not support installations");
- }
-
- @Override
- public Bundle getBundle(long id) {
- return getBundle();
- }
-
- @Override
- public Bundle[] getBundles() {
- return new Bundle[0];
- }
-
- @Override
- public void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException {
-
- }
-
- @Override
- public void addServiceListener(ServiceListener listener) {
-
- }
-
- @Override
- public void removeServiceListener(ServiceListener listener) {
-
- }
-
- @Override
- public void addBundleListener(BundleListener listener) {
-
- }
-
- @Override
- public void removeBundleListener(BundleListener listener) {
-
- }
-
- @Override
- public void addFrameworkListener(FrameworkListener listener) {
-
- }
-
- @Override
- public void removeFrameworkListener(FrameworkListener listener) {
-
- }
-
- @Override
- public ServiceRegistration> registerService(String[] clazzes, Object service, Dictionary properties) {
- throw new IllegalStateException("this is not OSGi!");
- }
-
- @Override
- public ServiceRegistration> registerService(String clazz, Object service, Dictionary properties) {
- throw new IllegalStateException("this is not OSGi!");
- }
-
- @Override
- public ServiceRegistration registerService(Class clazz, S service, Dictionary properties) {
- throw new IllegalStateException("this is not OSGi!");
- }
-
- @Override
- public ServiceRegistration registerService(Class clazz, ServiceFactory factory,
- Dictionary properties) {
- throw new IllegalStateException("this is not OSGi!");
- }
-
- @Override
- public ServiceReference>[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
- return new ServiceReference>[0];
- }
-
- @Override
- public ServiceReference>[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
- return new ServiceReference>[0];
- }
-
- @Override
- public ServiceReference> getServiceReference(String clazz) {
- throw new IllegalStateException("this is not OSGi!");
- }
-
- @Override
- public ServiceReference getServiceReference(Class clazz) {
- throw new IllegalStateException("this is not OSGi!");
- }
-
- @Override
- public Collection> getServiceReferences(Class clazz, String filter)
- throws InvalidSyntaxException {
- return Collections.emptyList();
- }
-
- @Override
- public S getService(ServiceReference reference) {
- throw new IllegalStateException("this is not OSGi!");
- }
-
- @Override
- public boolean ungetService(ServiceReference> reference) {
- return true;
- }
-
- @Override
- public ServiceObjects getServiceObjects(ServiceReference reference) {
- throw new IllegalStateException("this is not OSGi!");
- }
-
- @Override
- public File getDataFile(String filename) {
- return null;
- }
-
- @Override
- public Filter createFilter(String filter) throws InvalidSyntaxException {
- return FilterImpl.newInstance(filter);
- }
-
- @Override
- public Bundle getBundle(String location) {
- return getBundle();
- }
-
- @Override
- public void initialize() throws InitializationException {
- for (BundleActivator bundleActivator : legacyActivators) {
- try {
- bundleActivator.start(this);
- } catch (Exception e) {
- log.warn("Can't init " + bundleActivator.getClass() + "! (" + e + ")");
- }
- }
- }
-
- @Override
- public void dispose() {
- for (BundleActivator bundleActivator : legacyActivators) {
- try {
- bundleActivator.stop(this);
- } catch (Exception e) {
- log.warn("Can't init " + bundleActivator.getClass() + "! (" + e + ")");
- }
- }
- }
-
-}
diff --git a/p2-maven-plugin/src/main/resources/META-INF/sisu-connect.bundles b/p2-maven-plugin/src/main/resources/META-INF/sisu-connect.bundles
new file mode 100644
index 0000000000..98af23c4d3
--- /dev/null
+++ b/p2-maven-plugin/src/main/resources/META-INF/sisu-connect.bundles
@@ -0,0 +1,46 @@
+#################################################
+# This contains a list of bundles that should #
+# be included in the connect osgi framework #
+# and if these should be started #
+# Bundles are started in the given order #
+#################################################
+
+org.apache.felix.scr,true
+org.eclipse.equinox.common,true
+org.eclipse.ecf,true
+org.eclipse.ecf.filetransfer,true
+org.eclipse.ecf.identity,true
+org.eclipse.ecf.provider.filetransfer,true
+org.eclipse.equinox.p2.core,true
+org.eclipse.equinox.p2.artifact.repository,true
+org.eclipse.equinox.p2.director,true
+org.eclipse.equinox.p2.engine,true
+org.eclipse.equinox.p2.jarprocessor,true
+org.eclipse.equinox.p2.metadata,true
+org.eclipse.equinox.p2.metadata.repository,true
+org.eclipse.equinox.p2.publisher,true
+org.eclipse.equinox.p2.publisher.eclipse,true
+org.eclipse.equinox.p2.repository,true
+org.eclipse.equinox.p2.transport.ecf,true
+org.eclipse.equinox.p2.updatesite,true
+org.eclipse.osgi.compatibility.state
+org.eclipse.core.jobs
+org.eclipse.equinox.app
+org.eclipse.equinox.concurrent
+org.eclipse.equinox.frameworkadmin
+org.eclipse.equinox.frameworkadmin.equinox
+org.eclipse.equinox.preferences
+org.eclipse.equinox.registry,true
+org.eclipse.equinox.security
+org.eclipse.equinox.simpleconfigurator
+org.eclipse.equinox.simpleconfigurator.manipulator
+org.osgi.namespace.extender
+org.osgi.service.component
+org.osgi.service.prefs
+org.osgi.util.function
+org.osgi.util.promise
+org.sat4j.core
+org.sat4j.pb
+org.tukaani.xz
+bcpg
+bcprov
\ No newline at end of file
diff --git a/sisu-osgi/pom.xml b/sisu-osgi/pom.xml
index 41e54d7b91..d55d3fdc25 100644
--- a/sisu-osgi/pom.xml
+++ b/sisu-osgi/pom.xml
@@ -29,6 +29,7 @@
sisu-osgi-api
sisu-equinox-embedder
sisu-equinox-launching
+ sisu-osgi-connect
diff --git a/sisu-osgi/sisu-osgi-connect/pom.xml b/sisu-osgi/sisu-osgi-connect/pom.xml
new file mode 100644
index 0000000000..fc45c757f2
--- /dev/null
+++ b/sisu-osgi/sisu-osgi-connect/pom.xml
@@ -0,0 +1,56 @@
+
+ 4.0.0
+
+ org.eclipse.tycho
+ sisu-osgi
+ 3.0.0-SNAPSHOT
+
+ sisu-osgi-connect
+ Sisu Implementation of the OSGi R8 Framework Connect Specification
+
+
+
+ org.eclipse.tycho
+ sisu-osgi-api
+ ${project.version}
+
+
+ org.eclipse.platform
+ org.eclipse.osgi
+
+
+ org.osgi
+ org.osgi.service.component
+ 1.5.0
+
+
+ org.eclipse.sisu
+ org.eclipse.sisu.plexus
+
+
+ org.codehaus.plexus
+ plexus-component-annotations
+
+
+ commons-io
+ commons-io
+ 2.11.0
+
+
+
+
+
+
+ org.codehaus.plexus
+ plexus-component-metadata
+
+
+
+ generate-metadata
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sisu-osgi/sisu-osgi-connect/src/main/java/org/eclipse/sisu/osgi/connect/PlexusConnectContent.java b/sisu-osgi/sisu-osgi-connect/src/main/java/org/eclipse/sisu/osgi/connect/PlexusConnectContent.java
new file mode 100644
index 0000000000..4a968bebcf
--- /dev/null
+++ b/sisu-osgi/sisu-osgi-connect/src/main/java/org/eclipse/sisu/osgi/connect/PlexusConnectContent.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Christoph Läubrich and others.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christoph Läubrich - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sisu.osgi.connect;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.stream.Collectors;
+import java.util.zip.ZipEntry;
+
+import org.osgi.framework.connect.ConnectContent;
+import org.osgi.framework.connect.ConnectModule;
+
+/**
+ * Implements the {@link ConnectContent} on top of a jar file and a classloader
+ *
+ */
+class PlexusConnectContent implements ConnectContent, ConnectModule {
+ private ClassLoader classLoader;
+ private Optional