dropping @ImplicitActivator for @Header standard annotation
diff --git a/README.adoc b/README.adoc
index 85ed401..0f408c7 100644
--- a/README.adoc
+++ b/README.adoc
@@ -112,14 +112,14 @@
Then package it as a normal jar/exploded folder - not even a bundle - and add it
in the previous classpath. You can now run "test:hello".
-Note that to shortcut the build phase you can use `@ImplicitActivator`
+Note that to shortcut the build phase you can use `@Header`
which to define a `BundleActivator`.
Here is an example:
[source,java]
----
-@ImplicitActivator
+@Header(name= Constants.BUNDLE_ACTIVATOR, value = "${@class}")
public class MyBundleActivator implements BundleActivator {
// standard code
}
diff --git a/winegrower-core/pom.xml b/winegrower-core/pom.xml
index bb6fc1a..dd34ca2 100644
--- a/winegrower-core/pom.xml
+++ b/winegrower-core/pom.xml
@@ -47,6 +47,12 @@
<artifactId>osgi.cmpn</artifactId>
</dependency>
<dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>osgi.annotation</artifactId>
+ <version>7.0.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-finder-shaded</artifactId>
</dependency>
diff --git a/winegrower-core/src/main/java/org/apache/winegrower/Ripener.java b/winegrower-core/src/main/java/org/apache/winegrower/Ripener.java
index 271eeb2..f639afb 100644
--- a/winegrower-core/src/main/java/org/apache/winegrower/Ripener.java
+++ b/winegrower-core/src/main/java/org/apache/winegrower/Ripener.java
@@ -54,7 +54,7 @@
import org.apache.winegrower.deployer.OSGiBundleLifecycle;
import org.apache.winegrower.scanner.StandaloneScanner;
-import org.apache.winegrower.scanner.manifest.ActivatorManifestContributor;
+import org.apache.winegrower.scanner.manifest.HeaderManifestContributor;
import org.apache.winegrower.scanner.manifest.KarafCommandManifestContributor;
import org.apache.winegrower.scanner.manifest.ManifestContributor;
import org.apache.winegrower.scanner.manifest.OSGIInfContributor;
@@ -66,7 +66,6 @@
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.cm.ConfigurationListener;
import org.osgi.service.event.EventAdmin;
-import org.osgi.service.event.EventHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -105,7 +104,7 @@
private Collection<String> ignoredBundles = emptyList();
private Collection<ManifestContributor> manifestContributors = Stream.concat(
// built-in
- Stream.of(new KarafCommandManifestContributor(), new ActivatorManifestContributor(), new OSGIInfContributor()),
+ Stream.of(new KarafCommandManifestContributor(), new HeaderManifestContributor(), new OSGIInfContributor()),
// extensions
StreamSupport.stream(ServiceLoader.load(ManifestContributor.class).spliterator(), false)
).collect(toList());
diff --git a/winegrower-core/src/main/java/org/apache/winegrower/api/ImplicitActivator.java b/winegrower-core/src/main/java/org/apache/winegrower/api/ImplicitActivator.java
deleted file mode 100644
index c86a77d..0000000
--- a/winegrower-core/src/main/java/org/apache/winegrower/api/ImplicitActivator.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Licensed 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.winegrower.api;
-
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * If moving to OSGi from Winegrower you will need to use winegrower:manifest goal.
- */
-@Target(TYPE)
-@Retention(RUNTIME)
-public @interface ImplicitActivator {}
diff --git a/winegrower-core/src/main/java/org/apache/winegrower/scanner/StandaloneScanner.java b/winegrower-core/src/main/java/org/apache/winegrower/scanner/StandaloneScanner.java
index 03d721a..7ee931a 100644
--- a/winegrower-core/src/main/java/org/apache/winegrower/scanner/StandaloneScanner.java
+++ b/winegrower-core/src/main/java/org/apache/winegrower/scanner/StandaloneScanner.java
@@ -123,7 +123,7 @@
final Archive jarArchive = archive(loader, it.url);
// we scan per archive to be able to create bundle after
try {
- final AnnotationFinder archiveFinder = new AnnotationFinder(jarArchive);
+ final AnnotationFinder archiveFinder = new AnnotationFinder(jarArchive, false);
final ManifestCreator manifestCreator = new ManifestCreator(it.file.getName());
configuration.getManifestContributors()
.forEach(c -> c.contribute(archiveFinder, manifestCreator));
diff --git a/winegrower-core/src/main/java/org/apache/winegrower/scanner/manifest/ActivatorManifestContributor.java b/winegrower-core/src/main/java/org/apache/winegrower/scanner/manifest/ActivatorManifestContributor.java
deleted file mode 100644
index d4883da..0000000
--- a/winegrower-core/src/main/java/org/apache/winegrower/scanner/manifest/ActivatorManifestContributor.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * Licensed 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.winegrower.scanner.manifest;
-
-import java.util.List;
-import java.util.function.Supplier;
-import java.util.jar.Manifest;
-
-import org.apache.winegrower.api.ImplicitActivator;
-import org.apache.xbean.finder.AnnotationFinder;
-
-public class ActivatorManifestContributor implements ManifestContributor {
-
- @Override
- public void contribute(final AnnotationFinder finder, final Supplier<Manifest> manifest) {
- final List<Class<?>> annotatedClasses = finder.findAnnotatedClasses(ImplicitActivator.class);
- switch (annotatedClasses.size()) {
- case 0:
- return;
- case 1:
- manifest.get().getMainAttributes().putValue("Bundle-Activator", annotatedClasses.iterator().next().getName());
- return;
- default:
- throw new IllegalArgumentException("You can't get more than one activator: " + annotatedClasses);
- }
- }
-}
diff --git a/winegrower-core/src/main/java/org/apache/winegrower/scanner/manifest/HeaderManifestContributor.java b/winegrower-core/src/main/java/org/apache/winegrower/scanner/manifest/HeaderManifestContributor.java
new file mode 100644
index 0000000..1b70bd0
--- /dev/null
+++ b/winegrower-core/src/main/java/org/apache/winegrower/scanner/manifest/HeaderManifestContributor.java
@@ -0,0 +1,166 @@
+/**
+ * Licensed 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.winegrower.scanner.manifest;
+
+import static java.util.stream.Collectors.toMap;
+import static org.apache.xbean.asm7.ClassReader.SKIP_CODE;
+import static org.apache.xbean.asm7.ClassReader.SKIP_DEBUG;
+import static org.apache.xbean.asm7.ClassReader.SKIP_FRAMES;
+import static org.apache.xbean.asm7.Opcodes.ASM7;
+
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.BiFunction;
+import java.util.function.Supplier;
+import java.util.jar.Manifest;
+import java.util.stream.Stream;
+
+import org.apache.xbean.asm7.AnnotationVisitor;
+import org.apache.xbean.asm7.ClassReader;
+import org.apache.xbean.asm7.ClassVisitor;
+import org.apache.xbean.finder.AnnotationFinder;
+
+public class HeaderManifestContributor implements ManifestContributor {
+
+ @Override
+ public void contribute(final AnnotationFinder finder, final Supplier<Manifest> manifest) {
+ final ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ final List<Class<?>> headerClasses;
+ final List<Class<?>> headersClasses;
+ try {
+ final Class<? extends Annotation> headerAnnotation = (Class<? extends Annotation>)
+ loader.loadClass("org.osgi.annotation.bundle.Header");
+ final Class<? extends Annotation> headersAnnotation = (Class<? extends Annotation>)
+ loader.loadClass("org.osgi.annotation.bundle.Headers");
+
+ headerClasses = finder.findAnnotatedClasses(headerAnnotation);
+ headersClasses = finder.findAnnotatedClasses(headersAnnotation);
+ if (headerClasses.isEmpty() && headersClasses.isEmpty()) { // reuse the finder to ensure it exists
+ return;
+ }
+ } catch (final Exception | Error e) {
+ return;
+ }
+
+ // read it in the bytecode since reflection can't help here
+ final Map<String, String> headers = Stream.concat(headersClasses.stream(), headerClasses.stream())
+ .flatMap(clazz -> read(loader, clazz))
+ .collect(toMap(header -> header.name, header -> header.value, (a, b) -> {
+ throw new UnsupportedOperationException("not called normally");
+ }, () -> new HashMap<String, String>() {
+ @Override // override to access the key which is important here
+ public String merge(final String key, final String value,
+ final BiFunction<? super String, ? super String, ? extends String> ignored) {
+ final String oldValue = get(key);
+ final String newValue = oldValue == null ? value : HeaderManifestContributor.this.mergeManifestValues(key, oldValue, value);
+ put(key, newValue);
+ return newValue;
+ }
+ }));
+ headers.forEach((k, v) -> manifest.get().getMainAttributes().putValue(k, v));
+ }
+
+ private Stream<KeyValue> read(final ClassLoader loader, final Class<?> clazz) {
+ try (final InputStream stream = loader.getResourceAsStream(clazz.getName().replace('.', '/') + ".class")) {
+ final ClassReader reader = new ClassReader(stream);
+ final Collection<KeyValue> headers = new ArrayList<>();
+ final Supplier<AnnotationVisitor> newHeaderVisitor = () -> new AnnotationVisitor(ASM7) {
+ private final KeyValue header = new KeyValue();
+
+ @Override
+ public void visit(final String name, final Object value) {
+ switch (name) {
+ case "name":
+ header.name = String.valueOf(value);
+ break;
+ case "value":
+ header.value = String.valueOf(value)
+ .replace("${@class}", clazz.getName());
+ break;
+ default:
+ }
+ }
+
+ @Override
+ public void visitEnd() {
+ headers.add(header);
+ }
+ };
+
+ reader.accept(new ClassVisitor(ASM7) {
+ @Override
+ public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+ switch (descriptor) {
+ case "Lorg/osgi/annotation/bundle/Headers;":
+ return new PluralAnnotationVisitor("Lorg/osgi/annotation/bundle/Header;", newHeaderVisitor);
+ case "Lorg/osgi/annotation/bundle/Header;":
+ return newHeaderVisitor.get();
+ default:
+ return super.visitAnnotation(descriptor, visible);
+ }
+ }
+ }, SKIP_CODE + SKIP_DEBUG + SKIP_FRAMES);
+
+ return headers.stream();
+ } catch (final Exception e) {
+ return Stream.empty();
+ }
+ }
+
+ private String mergeManifestValues(final String key, final String value1, final String value2) {
+ if ("Bundle-Activator".equals(key)) { // can't take 2 values
+ throw new IllegalArgumentException("Conflicting activators: " + value1 + ", " + value2);
+ }
+ return value1 + "," + value2;
+ }
+
+ private static class KeyValue {
+ private String name;
+ private String value;
+ }
+
+ private static class PluralAnnotationVisitor extends AnnotationVisitor {
+ private final String singular;
+ private final Supplier<AnnotationVisitor> visitor;
+
+ private PluralAnnotationVisitor(final String singular, final Supplier<AnnotationVisitor> nestedVisitor) {
+ super(ASM7);
+ this.visitor = nestedVisitor;
+ this.singular = singular;
+ }
+
+ @Override
+ public AnnotationVisitor visitArray(final String name) {
+ switch (name) {
+ case "value":
+ return new AnnotationVisitor(ASM7) {
+ @Override
+ public AnnotationVisitor visitAnnotation(final String name, final String descriptor) {
+ if (singular.equals(descriptor)) {
+ return visitor.get();
+ }
+ return super.visitAnnotation(name, descriptor);
+ }
+ };
+ default:
+ return super.visitArray(name);
+ }
+ }
+ }
+}
diff --git a/winegrower-core/src/test/java/org/apache/winegrower/RipenerTest.java b/winegrower-core/src/test/java/org/apache/winegrower/RipenerTest.java
index 4ade23e..9845a30 100644
--- a/winegrower-core/src/test/java/org/apache/winegrower/RipenerTest.java
+++ b/winegrower-core/src/test/java/org/apache/winegrower/RipenerTest.java
@@ -33,6 +33,7 @@
import org.apache.winegrower.test.WithRipener;
import org.apache.winegrower.test.WithRipener.Entry;
import org.apache.winegrower.test.WithRipener.Service;
+import org.apache.winegrower.test.implicitactivator.ImplictActivator;
import org.apache.winegrower.test.simpleactivator.MyActivator;
import org.junit.jupiter.api.Test;
import org.osgi.framework.Bundle;
@@ -85,13 +86,31 @@
@Test
@WithRipener
void ensureFrameworkBundle(@Service final Ripener ripener) {
- assertEquals(3, ripener.getRegistry().getBundles().size());
+ assertEquals(4, ripener.getRegistry().getBundles().size());
+ }
+
+ @Test
+ @WithRipener(includeResources = @Entry(path = "org.apache.winegrower.test.implicitactivator"))
+ void implicitActivator(@Service final Ripener ripener) {
+ assertEquals(5, ripener.getRegistry().getBundles().size());
+
+ final BundleActivatorHandler activatorHandler = ripener.getRegistry().getBundles().values().stream()
+ .filter(it -> it.getActivator() != null)
+ .findFirst()
+ .orElseThrow(IllegalStateException::new)
+ .getActivator();
+ assertNotNull(activatorHandler);
+ final BundleActivator activator = activatorHandler.getActivator();
+ assertNotNull(activator);
+ assertTrue(ImplictActivator.class.isInstance(activator));
+ assertTrue(ImplictActivator.started);
+ ripener.stop();
}
@Test
@WithRipener(includeResources = @Entry(path = "org.apache.winegrower.test.simpleactivator"))
void simpleActivator(@Service final Ripener ripener) {
- assertEquals(4, ripener.getRegistry().getBundles().size());
+ assertEquals(5, ripener.getRegistry().getBundles().size());
final BundleActivatorHandler activatorHandler = ripener.getRegistry().getBundles().values().stream()
.filter(it -> it.getActivator() != null)
diff --git a/winegrower-core/src/test/java/org/apache/winegrower/deployer/BundleImplTest.java b/winegrower-core/src/test/java/org/apache/winegrower/deployer/BundleImplTest.java
index 50c6ecb..b5f9218 100644
--- a/winegrower-core/src/test/java/org/apache/winegrower/deployer/BundleImplTest.java
+++ b/winegrower-core/src/test/java/org/apache/winegrower/deployer/BundleImplTest.java
@@ -97,13 +97,13 @@
@Test
void getResource() {
assertNotNull(bundle.getResource("org"));
- assertNull(bundle.getResource("javax"));
+ assertNull(bundle.getResource("javax/enterprise"));
}
@Test
void getResources() throws IOException {
assertTrue(bundle.getResources("org").hasMoreElements());
- assertFalse(bundle.getResources("javax").hasMoreElements());
+ assertFalse(bundle.getResources("javax/enterprise").hasMoreElements());
}
@Test
diff --git a/winegrower-core/src/test/java/org/apache/winegrower/test/implicitactivator/ImplictActivator.java b/winegrower-core/src/test/java/org/apache/winegrower/test/implicitactivator/ImplictActivator.java
index 86abf6f..99191f4 100644
--- a/winegrower-core/src/test/java/org/apache/winegrower/test/implicitactivator/ImplictActivator.java
+++ b/winegrower-core/src/test/java/org/apache/winegrower/test/implicitactivator/ImplictActivator.java
@@ -13,11 +13,13 @@
*/
package org.apache.winegrower.test.implicitactivator;
-import org.apache.winegrower.api.ImplicitActivator;
+import static org.osgi.framework.Constants.BUNDLE_ACTIVATOR;
+
+import org.osgi.annotation.bundle.Header;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
-@ImplicitActivator
+@Header(name = BUNDLE_ACTIVATOR, value = "${@class}")
public class ImplictActivator implements BundleActivator {
public static boolean started;
diff --git a/winegrower-examples/http/src/main/java/org/apache/winegrower/examples/http/ExampleServlet.java b/winegrower-examples/http/src/main/java/org/apache/winegrower/examples/http/ExampleServlet.java
index 6f9667d..d5dac06 100644
--- a/winegrower-examples/http/src/main/java/org/apache/winegrower/examples/http/ExampleServlet.java
+++ b/winegrower-examples/http/src/main/java/org/apache/winegrower/examples/http/ExampleServlet.java
@@ -22,7 +22,6 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.apache.winegrower.api.ImplicitActivator;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
@@ -36,7 +35,6 @@
}
}
- @ImplicitActivator
public static class Registrar implements BundleActivator {
@Override
diff --git a/winegrower-examples/simple/README.adoc b/winegrower-examples/simple/README.adoc
index b6d099f..5601c2c 100644
--- a/winegrower-examples/simple/README.adoc
+++ b/winegrower-examples/simple/README.adoc
@@ -2,7 +2,7 @@
This example is the minimum application you can create with Winegrower.
-Your application is a regular jar with a Winegrower activator entry point (a class annotation with `@ImplicitActivator`).
+Your application is a regular jar with a Winegrower activator entry point (a class annotation with `@Header(name="Bundle-Activator", ...)`).
NB: this simple example is not OSGi compatible, it only runs with Winegrower.
diff --git a/winegrower-examples/simple/src/main/java/org/apache/winegrower/examples/Simple.java b/winegrower-examples/simple/src/main/java/org/apache/winegrower/examples/Simple.java
index 9b4b679..17abadf 100644
--- a/winegrower-examples/simple/src/main/java/org/apache/winegrower/examples/Simple.java
+++ b/winegrower-examples/simple/src/main/java/org/apache/winegrower/examples/Simple.java
@@ -13,11 +13,9 @@
*/
package org.apache.winegrower.examples;
-import org.apache.winegrower.api.ImplicitActivator;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
-@ImplicitActivator
public class Simple implements BundleActivator {
public void start(BundleContext bundleContext) {
diff --git a/winegrower-extension/winegrower-build/winegrower-build-common/src/main/java/org/apache/winegrower/extension/build/common/ManifestCreator.java b/winegrower-extension/winegrower-build/winegrower-build-common/src/main/java/org/apache/winegrower/extension/build/common/ManifestCreator.java
deleted file mode 100644
index ff740ab..0000000
--- a/winegrower-extension/winegrower-build/winegrower-build-common/src/main/java/org/apache/winegrower/extension/build/common/ManifestCreator.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
- * Licensed 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.winegrower.extension.build.common;
-
-import static java.util.Arrays.asList;
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.toList;
-import static org.apache.xbean.finder.archive.ClasspathArchive.archive;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.jar.Manifest;
-import java.util.stream.Stream;
-
-import org.apache.winegrower.scanner.manifest.ManifestContributor;
-import org.apache.xbean.finder.AnnotationFinder;
-
-public class ManifestCreator implements Runnable {
- private final Configuration configuration;
-
- public ManifestCreator(final Configuration configuration) {
- this.configuration = configuration;
- }
-
- @Override
- public void run() {
- if (!configuration.moduleToScan.exists()) {
- return;
- }
-
- final Manifest manifest = new Manifest();
- if (configuration.manifestBase != null && configuration.manifestBase.exists()) {
- try (final InputStream stream = new FileInputStream(configuration.manifestBase)) {
- manifest.read(stream);
- } catch (final IOException e) {
- throw new IllegalArgumentException(e);
- }
- } else {
- manifest.getMainAttributes().putValue("Manifest-Version", "1.0");
- }
- ofNullable(configuration.entries).ifPresent(kv -> kv.forEach((k, v) -> manifest.getMainAttributes().putValue(k, v)));
-
- final ClassLoader startingLoader = Thread.currentThread().getContextClassLoader();
- final List<ManifestContributor> creators = ofNullable(configuration.manifestCreators)
- .map(contributors -> contributors.stream().map(clazz -> {
- try {
- return startingLoader.loadClass(clazz).getConstructor().newInstance();
- } catch (final InstantiationException | NoSuchMethodException | IllegalAccessException
- | ClassNotFoundException e) {
- throw new IllegalArgumentException(e);
- } catch (final InvocationTargetException e) {
- throw new IllegalArgumentException(e.getTargetException());
- }
- }).map(ManifestContributor.class::cast).collect(toList())).orElseGet(Collections::emptyList);
-
- try (final URLClassLoader loader = createLoader()) {
- final AnnotationFinder finder = new AnnotationFinder(archive(loader, configuration.moduleToScan.toURI().toURL()), false);
- creators.forEach(contributor -> contributor.contribute(finder, () -> manifest));
- } catch (final IOException e) {
- throw new IllegalStateException(e);
- }
- configuration.output.getParentFile().mkdirs();
- try (final OutputStream outputStream = new FileOutputStream(configuration.output)) {
- manifest.write(outputStream);
- } catch (IOException e) {
- throw new IllegalArgumentException(e);
- }
- }
-
- private URLClassLoader createLoader() {
- return new URLClassLoader(
- Stream.concat(
- Stream.of(configuration.moduleToScan),
- configuration.libToAddInClassLoader.stream())
- .filter(File::exists)
- .map(file -> {
- try {
- return file.toURI().toURL();
- } catch (final MalformedURLException e) {
- throw new IllegalStateException(e);
- }
- })
- .toArray(URL[]::new),
- Thread.currentThread().getContextClassLoader());
- }
-
- public static class Configuration {
- private final Collection<File> libToAddInClassLoader;
- private final File moduleToScan;
- private final Collection<String> manifestCreators;
- private final File manifestBase;
- private final Map<String, String> entries;
- private final File output;
-
- public Configuration(final Collection<File> libToAddInClassLoader,
- final File moduleToScan,
- final Collection<String> manifestCreators,
- final File manifestBase,
- final Map<String, String> entries,
- final File output) {
- this.libToAddInClassLoader = libToAddInClassLoader;
- this.moduleToScan = moduleToScan;
- this.manifestCreators = manifestCreators;
- this.manifestBase = manifestBase;
- this.entries = entries;
- this.output = output;
- }
- }
-}
diff --git a/winegrower-extension/winegrower-build/winegrower-build-common/src/test/java/org/Activator.java b/winegrower-extension/winegrower-build/winegrower-build-common/src/test/java/org/Activator.java
deleted file mode 100644
index 8f43581..0000000
--- a/winegrower-extension/winegrower-build/winegrower-build-common/src/test/java/org/Activator.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org;
-
-import org.apache.winegrower.api.ImplicitActivator;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-
-@ImplicitActivator
-public class Activator implements BundleActivator {
- public void start(BundleContext context) {
- // no-op
- }
-
- public void stop(BundleContext context) {
- // no-op
- }
-}
diff --git a/winegrower-extension/winegrower-build/winegrower-build-common/src/test/java/org/apache/winegrower/extension/build/common/ManifestCreatorTest.java b/winegrower-extension/winegrower-build/winegrower-build-common/src/test/java/org/apache/winegrower/extension/build/common/ManifestCreatorTest.java
deleted file mode 100644
index caeb961..0000000
--- a/winegrower-extension/winegrower-build/winegrower-build-common/src/test/java/org/apache/winegrower/extension/build/common/ManifestCreatorTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/**
- * Licensed 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.winegrower.extension.build.common;
-
-import static java.util.Collections.emptyList;
-import static java.util.Collections.singletonList;
-import static java.util.Collections.singletonMap;
-import static org.apache.xbean.asm7.Opcodes.ACC_PUBLIC;
-import static org.apache.xbean.asm7.Opcodes.ACC_SUPER;
-import static org.apache.xbean.asm7.Opcodes.ALOAD;
-import static org.apache.xbean.asm7.Opcodes.INVOKESPECIAL;
-import static org.apache.xbean.asm7.Opcodes.RETURN;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.jar.Attributes;
-import java.util.jar.JarEntry;
-import java.util.jar.JarInputStream;
-import java.util.jar.JarOutputStream;
-import java.util.jar.Manifest;
-
-import org.apache.winegrower.scanner.manifest.ActivatorManifestContributor;
-import org.apache.xbean.asm7.ClassWriter;
-import org.apache.xbean.asm7.MethodVisitor;
-import org.junit.jupiter.api.Test;
-
-class ManifestCreatorTest {
- @Test
- void create() {
- final File output = new File("target/manifest/create.jar");
- final File module = createModuleWithActivator(new File(output.getParentFile(), "module.jar"));
- if (output.exists()) {
- output.delete();
- }
- new ManifestCreator(new ManifestCreator.Configuration(
- emptyList(),
- module,
- singletonList(ActivatorManifestContributor.class.getName()),
- null,
- singletonMap("test", "true"),
- output
- )).run();
- assertTrue(output.exists());
- final Manifest manifest = new Manifest();
- try (final InputStream in = new FileInputStream(output)) {
- manifest.read(in);
- } catch (final IOException e) {
- throw new IllegalStateException(e);
- }
- final Attributes mainAttributes = manifest.getMainAttributes();
- assertEquals("1.0", mainAttributes.getValue("Manifest-Version"));
- assertEquals("org.Activator", mainAttributes.getValue("Bundle-Activator"));
- assertEquals("true", mainAttributes.getValue("test"));
- }
-
- private File createModuleWithActivator(final File file) {
- file.getParentFile().mkdirs();
- try (final JarOutputStream out = new JarOutputStream(new FileOutputStream(file))) {
- out.putNextEntry(new JarEntry("org/"));
- out.closeEntry();
-
- out.putNextEntry(new JarEntry("org/Activator.class"));
-
- final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
- cw.visit(52, ACC_PUBLIC + ACC_SUPER, "org/Activator", null, "java/lang/Object", new String[] { "org/osgi/framework/BundleActivator" });
- cw.visitAnnotation("Lorg/apache/winegrower/api/ImplicitActivator;", true).visitEnd();
- {
- final MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
- mv.visitCode();
- mv.visitVarInsn(ALOAD, 0);
- mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
- mv.visitInsn(RETURN);
- mv.visitMaxs(1, 1);
- mv.visitEnd();
- }
- {
- final MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "start", "(Lorg/osgi/framework/BundleContext;)V", null, null);
- mv.visitCode();
- mv.visitInsn(RETURN);
- mv.visitMaxs(0, 2);
- mv.visitEnd();
- }
- {
- final MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "stop", "(Lorg/osgi/framework/BundleContext;)V", null, null);
- mv.visitCode();
- mv.visitInsn(RETURN);
- mv.visitMaxs(0, 2);
- mv.visitEnd();
- }
- cw.visitEnd();
-
- out.write(cw.toByteArray());
- out.closeEntry();
- } catch (final IOException e) {
- throw new IllegalStateException(e);
- }
- return file;
- }
-}
diff --git a/winegrower-extension/winegrower-build/winegrower-maven-plugin/src/main/asciidoc/index.adoc b/winegrower-extension/winegrower-build/winegrower-maven-plugin/src/main/asciidoc/index.adoc
index 14eec1a..6fa116b 100644
--- a/winegrower-extension/winegrower-build/winegrower-maven-plugin/src/main/asciidoc/index.adoc
+++ b/winegrower-extension/winegrower-build/winegrower-maven-plugin/src/main/asciidoc/index.adoc
@@ -125,23 +125,7 @@
Winegrower supports some custom API not requiring a full OSGi packaging
and in particular a valid OSGi `META-INF/MANIFEST.MF`. This is typically the case
-if you are using `@ImplicitActivator`.
+if you are using `@Header`.
If you want to enable this feature you can either register the activator
-manually through bnd or bundle plugins but you can also use `winegrower:manifest` goal
-which will create a manifest with all the supported features.
-
-TIP: you can mix this tool with another manifest generator using `manifestBase` configuration.
-
-=== Configuration
-
-
-[cols="e,m,m,m,a",headers]
-|===
-|Name|Type|Property|Default|Description
-|classes|File|winegrower.classes|${project.build.outputDirectory}|The module to consider for the created manifest file.
-|output|File|winegrower.output|${project.build.outputDirectory}/META-INF/MANIFEST.MF|Where to create the manifest file.
-|manifestBase|File|winegrower.manifestBase|-|Path to an existing manifest used as base for the one the plugin will create.
-|customEntries|Map<String, String>|winegrower.customEntries|-|A map of entries to add to the manifest.
-|manifestContributors|List<String>|winegrower.manifestContributors|built in ones|The manifest contributors to use for this generation. It is a fully qualified list of implementations of `ManifestContributor`.
-|===
+manually or we recommand you to use bnd or bundle plugins to do that.
diff --git a/winegrower-extension/winegrower-build/winegrower-maven-plugin/src/main/java/org/apache/winegrower/extension/build/maven/ManifestMojo.java b/winegrower-extension/winegrower-build/winegrower-maven-plugin/src/main/java/org/apache/winegrower/extension/build/maven/ManifestMojo.java
deleted file mode 100644
index 0308091..0000000
--- a/winegrower-extension/winegrower-build/winegrower-maven-plugin/src/main/java/org/apache/winegrower/extension/build/maven/ManifestMojo.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * Licensed 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.winegrower.extension.build.maven;
-
-import static java.util.stream.Collectors.toList;
-import static org.apache.maven.plugins.annotations.ResolutionScope.RUNTIME_PLUS_SYSTEM;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Objects;
-import java.util.stream.Stream;
-
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugins.annotations.Mojo;
-import org.apache.maven.plugins.annotations.Parameter;
-import org.apache.maven.project.MavenProject;
-import org.apache.winegrower.extension.build.common.ManifestCreator;
-
-@Mojo(name = "manifest", requiresDependencyResolution = RUNTIME_PLUS_SYSTEM)
-public class ManifestMojo extends AbstractMojo {
- @Parameter(defaultValue = "${project}", readonly = true, required = true)
- private MavenProject project;
-
- @Parameter(defaultValue = "${project.build.outputDirectory}", property = "winegrower.classes")
- private File classes;
-
- @Parameter(defaultValue = "${project.build.outputDirectory}/META-INF/MANIFEST.MF", property = "winegrower.output")
- private File output;
-
- @Parameter(property = "winegrower.manifestBase")
- private File manifestBase;
-
- @Parameter(property = "winegrower.customEntries")
- private Map<String, String> customEntries;
-
- @Parameter(defaultValue = "org.apache.winegrower.scanner.manifest.ActivatorManifestContributor," +
- "org.apache.winegrower.scanner.manifest.KarafCommandManifestContributor," +
- "org.apache.winegrower.scanner.manifest.OSGIInfContributor", property = "winegrower.manifestContributors")
- private Collection<String> manifestContributors;
-
- @Override
- public void execute() {
- new ManifestCreator(new ManifestCreator.Configuration(
- collectClassLoaderFiles(),
- classes,
- manifestContributors,
- manifestBase,
- customEntries,
- output
- )).run();
- }
-
- private Collection<File> collectClassLoaderFiles() {
- return Stream.concat(
- project.getArtifacts().stream().map(Artifact::getFile),
- Stream.of(classes))
- .filter(Objects::nonNull)
- .filter(File::exists)
- .collect(toList());
- }
-}
diff --git a/winegrower-extension/winegrower-servlet/src/test/java/org/apache/winegrower/servlet/RipenerLifecycleTest.java b/winegrower-extension/winegrower-servlet/src/test/java/org/apache/winegrower/servlet/RipenerLifecycleTest.java
index efc1d34..3a26585 100644
--- a/winegrower-extension/winegrower-servlet/src/test/java/org/apache/winegrower/servlet/RipenerLifecycleTest.java
+++ b/winegrower-extension/winegrower-servlet/src/test/java/org/apache/winegrower/servlet/RipenerLifecycleTest.java
@@ -38,7 +38,6 @@
import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.apache.meecrowave.testing.ConfigurationInject;
import org.apache.winegrower.Ripener;
-import org.apache.winegrower.api.ImplicitActivator;
import org.apache.winegrower.api.InjectedService;
import org.junit.jupiter.api.Test;
import org.osgi.framework.BundleActivator;
@@ -84,7 +83,6 @@
}
}
- @ImplicitActivator
public static class Registrar implements BundleActivator {
@Override