This is an automated email from the ASF dual-hosted git repository.

kwin pushed a commit to branch feature-analyzer-for-classes
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git

commit fa8423eb3b5034400d57ac54ddc09f712c40c20e
Author: Konrad Windszus <[email protected]>
AuthorDate: Mon Oct 9 11:29:46 2023 +0200

    SLING-12026 Check for implementations/extension of provider types
    
    New feature analyser module for class-related analysers, leveraging ASM
---
 .../.gitignore                                     |  18 +++
 org.apache.sling.feature.analyser.classes/pom.xml  | 143 ++++++++++++++++++++
 .../readme.md                                      |  18 +++
 .../impl/ArtifactContextAwareClassVisitor.java     |  52 +++++++
 .../impl/CheckProviderTypeImplementations.java     | 149 +++++++++++++++++++++
 .../impl/CheckProviderTypeImplementationsTest.java |  91 +++++++++++++
 .../src/test/resources/metadata-feature.json       |  74 ++++++++++
 .../src/test/resources/simplelogger.properties     |   1 +
 8 files changed, 546 insertions(+)

diff --git a/org.apache.sling.feature.analyser.classes/.gitignore 
b/org.apache.sling.feature.analyser.classes/.gitignore
new file mode 100644
index 00000000..c7f991ea
--- /dev/null
+++ b/org.apache.sling.feature.analyser.classes/.gitignore
@@ -0,0 +1,18 @@
+/target
+.idea
+.classpath
+.metadata
+.project
+.settings
+.externalToolBuilders
+maven-eclipse.xml
+*.swp
+*.iml
+*.ipr
+*.iws
+*.bak
+.vlt
+.vscode
+.DS_Store
+jcr.log
+atlassian-ide-plugin.xml
diff --git a/org.apache.sling.feature.analyser.classes/pom.xml 
b/org.apache.sling.feature.analyser.classes/pom.xml
new file mode 100644
index 00000000..bc05302f
--- /dev/null
+++ b/org.apache.sling.feature.analyser.classes/pom.xml
@@ -0,0 +1,143 @@
+<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.apache.sling</groupId>
+        <artifactId>sling-bundle-parent</artifactId>
+        <version>52</version>
+        <relativePath />
+    </parent>
+    <groupId>org.apache.sling</groupId>
+    <artifactId>org.apache.sling.feature.analyser.classes</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+
+    <name>Apache Sling Feature Model Analyser For Classes</name>
+    <description>Provides analysers which act on class level of bundles 
embedded
+        in features</description>
+
+    <properties>
+        <sling.java.version>11</sling.java.version>
+        
<project.build.outputTimestamp>1675867676</project.build.outputTimestamp>
+    </properties>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.junit</groupId>
+                <artifactId>junit-bom</artifactId>
+                <version>5.9.3</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.feature.analyser</artifactId>
+            <version>2.0.0</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jetbrains</groupId>
+            <artifactId>annotations</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.feature</artifactId>
+            <version>2.0.0</version>
+            <scope>compile</scope>
+        </dependency>
+        <!--transitive
+        but provided deps of sling.feature -->
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.annotation.versioning</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.framework</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.resource</artifactId>
+            <version>1.0.1</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.json</groupId>
+            <artifactId>jakarta.json-api</artifactId>
+            <version>2.0.2</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.util.converter</artifactId>
+            <version>1.0.9</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.feature</artifactId>
+            <version>1.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.utils</artifactId>
+            <version>1.11.8</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.cm.json</artifactId>
+            <version>2.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ow2.asm</groupId>
+            <artifactId>asm</artifactId>
+            <version>9.6</version>
+            <scope>compile</scope>
+        </dependency>
+        <!-- testing dependencies -->
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-library</artifactId>
+            <version>2.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.json</groupId>
+            <artifactId>jakarta.json-api</artifactId>
+            <version>2.0.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.johnzon</groupId>
+            <artifactId>johnzon-core</artifactId>
+            <classifier>jakarta</classifier>
+            <version>1.2.14</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/org.apache.sling.feature.analyser.classes/readme.md 
b/org.apache.sling.feature.analyser.classes/readme.md
new file mode 100644
index 00000000..9f65b60a
--- /dev/null
+++ b/org.apache.sling.feature.analyser.classes/readme.md
@@ -0,0 +1,18 @@
+[![Apache 
Sling](https://sling.apache.org/res/logos/sling.png)](https://sling.apache.org)
+
+&#32;[![Build 
Status](https://ci-builds.apache.org/job/Sling/job/modules/job/sling-org-apache-sling-feature-analyser/job/master/badge/icon)](https://ci-builds.apache.org/job/Sling/job/modules/job/sling-org-apache-sling-feature-analyser/job/master/)&#32;[![Test
 
Status](https://img.shields.io/jenkins/tests.svg?jobUrl=https://ci-builds.apache.org/job/Sling/job/modules/job/sling-org-apache-sling-feature-analyser/job/master/)](https://ci-builds.apache.org/job/Sling/job/modules/job/sling-org-a
 [...]
+
+# Feature Model Analyser For Classes
+
+This module contain analyser tasks which analyse classes contained in 
features' OSGi bundles.
+For further information about refer to [Sling Feature Model 
Analyser](https://github.com/apache/sling-org-apache-sling-feature-analyser)
+
+
+# Analyser Tasks
+
+Below is a list of built-in analysers.
+
+## `prevent-provider-type-impls`
+
+This analyser makes sure that no class implements or extends any type marked 
as provider with annotation 
[`org.osgi.annotation.versioning.ProviderType`](https://docs.osgi.org/javadoc/osgi.annotation/8.0.0/org/osgi/annotation/versioning/ProviderType.html).
+
diff --git 
a/org.apache.sling.feature.analyser.classes/src/main/java/org/apache/sling/feature/analyser/task/classes/impl/ArtifactContextAwareClassVisitor.java
 
b/org.apache.sling.feature.analyser.classes/src/main/java/org/apache/sling/feature/analyser/task/classes/impl/ArtifactContextAwareClassVisitor.java
new file mode 100644
index 00000000..96f8f20c
--- /dev/null
+++ 
b/org.apache.sling.feature.analyser.classes/src/main/java/org/apache/sling/feature/analyser/task/classes/impl/ArtifactContextAwareClassVisitor.java
@@ -0,0 +1,52 @@
+/*
+ * 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.sling.feature.analyser.task.classes.impl;
+
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.analyser.task.AnalyserTaskContext;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Opcodes;
+
+public abstract class ArtifactContextAwareClassVisitor extends ClassVisitor {
+
+    private final AnalyserTaskContext ctx;
+    private ArtifactId currentArtifactId;
+
+    ArtifactContextAwareClassVisitor(AnalyserTaskContext ctx) {
+        super(Opcodes.ASM9);
+        this.ctx = ctx;
+    }
+
+    /**
+     * Called for each visited artifact prior to all other method calls from 
{@link ClassVisitors}
+     * @param artifactId the artifact id of the currently visited class
+     */
+    public void visitArtifact(ArtifactId artifactId) {
+        this.currentArtifactId = artifactId;
+    }
+
+    /**
+     * Report an error in the context of the of the given {@link 
AnalyserTaskContext} 
+     * and the artifact given to {@link #visitArtifact(ArtifactId)}
+     * @param message the error message to emit
+     */
+    public void reportError(String message) {
+        ctx.reportArtifactError(currentArtifactId, message);
+    }
+}
diff --git 
a/org.apache.sling.feature.analyser.classes/src/main/java/org/apache/sling/feature/analyser/task/classes/impl/CheckProviderTypeImplementations.java
 
b/org.apache.sling.feature.analyser.classes/src/main/java/org/apache/sling/feature/analyser/task/classes/impl/CheckProviderTypeImplementations.java
new file mode 100644
index 00000000..05dcff0b
--- /dev/null
+++ 
b/org.apache.sling.feature.analyser.classes/src/main/java/org/apache/sling/feature/analyser/task/classes/impl/CheckProviderTypeImplementations.java
@@ -0,0 +1,149 @@
+/*
+ * 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.sling.feature.analyser.task.classes.impl;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+import org.apache.sling.feature.analyser.task.AnalyserTask;
+import org.apache.sling.feature.analyser.task.AnalyserTaskContext;
+import org.apache.sling.feature.scanner.BundleDescriptor;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CheckProviderTypeImplementations implements AnalyserTask {
+
+    private static final String PROVIDER_TYPE_ANNOTATION = 
"Lorg/osgi/annotation/versioning/ProviderType;";
+    private static final String MESSAGE = "Type %s %s provider type %s. This 
is not allowed!";
+
+    static final Logger LOG = 
LoggerFactory.getLogger(CheckProviderTypeImplementations.class);
+
+    @Override
+    public String getId() {
+        return "prevent-provider-type-impls";
+    }
+
+    @Override
+    public String getName() {
+        return "Prevents implementation or extension of types marked as 
Provider";
+    }
+
+    @Override
+    public void execute(AnalyserTaskContext ctx) throws Exception {
+        Set<String> providerTypes = collectProviderTypes(ctx);
+        LOG.debug("Provider types found: {}", providerTypes);
+        forEachClass(ctx, 
+                new 
ProhibitingSuperTypeAndImplementedInterfacesClassVisitor(ctx, providerTypes),
+                ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
+    }
+
+    private Set<String> collectProviderTypes(AnalyserTaskContext ctx) throws 
IOException {
+        AnnotatedTypeCollectorClassVisitor providerTypeCollector = new 
AnnotatedTypeCollectorClassVisitor(PROVIDER_TYPE_ANNOTATION);
+        forEachClass(ctx, providerTypeCollector, ClassReader.SKIP_DEBUG | 
ClassReader.SKIP_FRAMES);
+        return providerTypeCollector.getProviderTypes();
+    }
+
+    private static final class AnnotatedTypeCollectorClassVisitor extends 
ClassVisitor {
+
+        private final String annotationType;
+        private final Set<String> providerTypes;
+        private String currentClassName;
+
+        protected AnnotatedTypeCollectorClassVisitor(String annotationType) {
+            super(Opcodes.ASM9);
+            this.annotationType = annotationType;
+            this.providerTypes = new HashSet<>();
+        }
+
+        
+        @Override
+        public void visit(int version, int access, String name, String 
signature, String superName, String[] interfaces) {
+            currentClassName = name;
+        }
+
+        @Override
+        public AnnotationVisitor visitAnnotation(String descriptor, boolean 
visible) {
+            if (descriptor.equals(annotationType)) {
+                providerTypes.add(currentClassName);
+            }
+            return super.visitAnnotation(descriptor, visible);
+        }
+
+        public Set<String> getProviderTypes() {
+            return providerTypes;
+        }
+    }
+
+    static String internalToClassName(String internalName) {
+        return Type.getObjectType(internalName).getClassName();
+    }
+
+    private void forEachClass(AnalyserTaskContext ctx, ClassVisitor visitor, 
int parsingOptions) throws IOException {
+        for (BundleDescriptor bundleDescriptor : 
ctx.getFeatureDescriptor().getBundleDescriptors()) {
+            URL url = bundleDescriptor.getArtifactFile();
+            LOG.debug("Checking classes in bundle {}", url);
+            try (final JarInputStream jis = new 
JarInputStream(url.openStream())) {
+                if (visitor instanceof ArtifactContextAwareClassVisitor) {
+                    ArtifactContextAwareClassVisitor acacv = 
(ArtifactContextAwareClassVisitor)visitor;
+                    
acacv.visitArtifact(bundleDescriptor.getArtifact().getId());
+                }
+                forEachClass(jis, visitor, parsingOptions);
+            }
+        }
+    }
+
+    private void forEachClass(JarInputStream jarInputStream, ClassVisitor 
visitor, int parsingOptions) throws IOException {
+        JarEntry jarEntry;
+        while ((jarEntry = jarInputStream.getNextJarEntry()) != null) {
+            if (jarEntry.getName().endsWith(".class")) {
+                ClassReader classReader = new ClassReader(jarInputStream);
+                classReader.accept(visitor, parsingOptions);
+            }
+            jarInputStream.closeEntry();
+        }
+    }
+
+    private static final class 
ProhibitingSuperTypeAndImplementedInterfacesClassVisitor extends 
ArtifactContextAwareClassVisitor {
+
+        private final Set<String> prohibitedTypes;
+
+        protected 
ProhibitingSuperTypeAndImplementedInterfacesClassVisitor(AnalyserTaskContext 
ctx, Set<String> prohibitedTypes) {
+            super(ctx);
+            this.prohibitedTypes = prohibitedTypes;
+        }
+
+        @Override
+        public void visit(int version, int access, String name, String 
signature, String superName, String[] interfaces) {
+            if (prohibitedTypes.contains(superName)) {
+                reportError(String.format(MESSAGE, internalToClassName(name), 
"implements", internalToClassName(superName)));
+            }
+            
Arrays.stream(interfaces).filter(prohibitedTypes::contains).forEach(s -> 
reportError(String.format(MESSAGE, internalToClassName(name), "extends", 
internalToClassName(s))));
+        }
+    }
+}
diff --git 
a/org.apache.sling.feature.analyser.classes/src/test/java/org/apache/sling/feature/analyser/task/classes/impl/CheckProviderTypeImplementationsTest.java
 
b/org.apache.sling.feature.analyser.classes/src/test/java/org/apache/sling/feature/analyser/task/classes/impl/CheckProviderTypeImplementationsTest.java
new file mode 100644
index 00000000..2e881250
--- /dev/null
+++ 
b/org.apache.sling.feature.analyser.classes/src/test/java/org/apache/sling/feature/analyser/task/classes/impl/CheckProviderTypeImplementationsTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.sling.feature.analyser.task.classes.impl;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.analyser.Analyser;
+import org.apache.sling.feature.analyser.AnalyserResult;
+import org.apache.sling.feature.analyser.AnalyserResult.ArtifactReport;
+import org.apache.sling.feature.analyser.task.AnalyserTask;
+import org.apache.sling.feature.io.artifacts.ArtifactManager;
+import org.apache.sling.feature.io.artifacts.ArtifactManagerConfig;
+import org.apache.sling.feature.io.json.FeatureJSONReader;
+import org.apache.sling.feature.scanner.Scanner;
+import org.hamcrest.Description;
+import org.hamcrest.MatcherAssert;
+import org.hamcrest.Matchers;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.jupiter.api.Test;
+
+
+class CheckProviderTypeImplementationsTest {
+
+    @Test
+    void test() throws Exception {
+        AnalyserResult result = analyse("/metadata-feature.json", new 
CheckProviderTypeImplementations());
+        assertEquals(7, result.getArtifactErrors().size());
+        MatcherAssert.assertThat(result.getArtifactErrors(), Matchers.hasItem(
+                new 
ArtifactReportMatcher("org.apache.jackrabbit:oak-jackrabbit-api:1.56.0", 
+                        "Type 
org.apache.jackrabbit.api.security.JackrabbitAccessControlList extends provider 
type org.apache.jackrabbit.api.security.JackrabbitAccessControlPolicy. This is 
not allowed!")));
+        
+    }
+
+    private static final class ArtifactReportMatcher extends 
TypeSafeMatcher<ArtifactReport> {
+
+        private final ArtifactId id;
+        private final String value;
+        private final String taskId;
+
+        ArtifactReportMatcher(String mvnCoordinates, String value) {
+            this.id = ArtifactId.fromMvnId(mvnCoordinates);
+            this.value = value;
+            this.taskId = "prevent-provider-type-impls";
+        }
+
+        @Override
+        protected boolean matchesSafely(ArtifactReport item) {
+            return (item.getKey().equals(id)
+                && item.getValue().equals(value)
+                && item.getTaskId().equals(taskId));
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText( "ArtifactReport 
[").appendText(taskId).appendText("] ").appendText(id.toString()).appendText(": 
").appendText(value);
+        }
+    }
+
+    static AnalyserResult analyse(String featureResourceName, AnalyserTask... 
tasks) throws Exception {
+        final Feature feature;
+        try (Reader reader = new 
InputStreamReader(CheckProviderTypeImplementationsTest.class.getResourceAsStream(featureResourceName),
 StandardCharsets.UTF_8)) {
+            feature = FeatureJSONReader.read(reader, "");
+        }
+        ArtifactManagerConfig config = new ArtifactManagerConfig();
+        final Scanner scanner = new 
Scanner(ArtifactManager.getArtifactManager(config));
+        Analyser analyser = new Analyser(scanner, tasks);
+        return analyser.analyse(feature);
+    }
+}
diff --git 
a/org.apache.sling.feature.analyser.classes/src/test/resources/metadata-feature.json
 
b/org.apache.sling.feature.analyser.classes/src/test/resources/metadata-feature.json
new file mode 100644
index 00000000..782109da
--- /dev/null
+++ 
b/org.apache.sling.feature.analyser.classes/src/test/resources/metadata-feature.json
@@ -0,0 +1,74 @@
+{
+  "id": "org.acme:acmefeature:slingosgifeature:metadata-feature:0.0.1",
+  "bundles": [
+    "org.apache.jackrabbit:oak-jackrabbit-api:1.56.0"
+  ],
+  "analyser-metadata:JSON|false": {
+    "org.slf4j:jcl-over-slf4j:1.7.25": {
+      "manifest" : {
+        "Manifest-Version": "1.0",
+        "Archiver-Version": "Plexus Archiver",
+        "Created-By": "Apache Maven",
+        "Built-By": "ceki",
+        "Build-Jdk": "1.7.0_17",
+        "Bundle-Description": "JCL 1.2 implemented over SLF4J",
+        "Bundle-Version": "1.7.25",
+        "Implementation-Version": "1.7.25",
+        "X-Compile-Source-JDK": "1.5",
+        "X-Compile-Target-JDK": "1.5",
+        "Implementation-Title": "jcl-over-slf4j",
+        "Bundle-ManifestVersion": "2",
+        "Bundle-SymbolicName": "jcl.over.slf4j",
+        "Bundle-Name": "jcl-over-slf4j",
+        "Bundle-Vendor": "SLF4J.ORG",
+        "Bundle-RequiredExecutionEnvironment": "J2SE-1.5",
+        "Export-Package": "org.apache.commons.logging;version=1.2,  
org.apache.commons.logging.impl;version=1.2",
+        "Import-Package": "org.slf4j;version=1.7.25, 
org.slf4j.spi;version=1.7.25"
+      }
+    },
+    "org.slf4j:log4j-over-slf4j:1.7.25": {
+      "manifest" : {
+        "Manifest-Version": "2.0",
+        "Archiver-Version": "Plexus Archiver",
+        "Created-By": "Apache Maven",
+        "Built-By": "ceki",
+        "Build-Jdk": "1.7.0_17",
+        "Bundle-Description": "Log4j implemented over SLF4J",
+        "Bundle-Version": "1.7.25",
+        "Implementation-Version": "1.7.25",
+        "X-Compile-Source-JDK": "1.5",
+        "X-Compile-Target-JDK": "1.5",
+        "Implementation-Title": "log4j-over-slf4j",
+        "Bundle-ManifestVersion": "2",
+        "Bundle-SymbolicName": "log4j.over.slf4j",
+        "Bundle-Name": "log4j-over-slf4j",
+        "Bundle-Vendor": "SLF4J.ORG",
+        "Bundle-RequiredExecutionEnvironment": "J2SE-1.5",
+        "Export-Package": 
"org.apache.log4j;version=1.2.17,org.apache.log4j.helpers;version=1.2.17,org.apache.log4j.spi;version=1.2.17,org.apache.log4j.xml;version=1.2.17",
+        "Import-Package": 
"org.slf4j;version=1.6.0,org.slf4j.helpers;version=1.6.0,org.slf4j.spi;version=1.6.0"
+      }
+    },
+    "org.slf4j:slf4j-api:1.7.25": {
+      "manifest" : {
+        "Manifest-Version": "1.0",
+        "Archiver-Version": "Plexus Archiver",
+        "Created-By": "Apache Maven",
+        "Built-By": "ceki",
+        "Build-Jdk": "1.7.0_17",
+        "Bundle-Description": "The slf4j API",
+        "Bundle-Version": "1.7.25",
+        "Implementation-Version": "1.7.25",
+        "X-Compile-Source-JDK": "1.5",
+        "X-Compile-Target-JDK": "1.5",
+        "Implementation-Title": "slf4j-api",
+        "Bundle-ManifestVersion": "2",
+        "Bundle-SymbolicName": "slf4j.api",
+        "Bundle-Name": "slf4j-api",
+        "Bundle-Vendor": "SLF4J.ORG",
+        "Bundle-RequiredExecutionEnvironment": "J2SE-1.5",
+        "Export-Package": "org.slf4j;version=1.7.25, 
org.slf4j.spi;version=1.7.25, org.slf4j.helpers;version=1.7.25, 
org.slf4j.event;version=1.7.25",
+        "Import-Package": "org.slf4j.impl;version=1.6.0"
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git 
a/org.apache.sling.feature.analyser.classes/src/test/resources/simplelogger.properties
 
b/org.apache.sling.feature.analyser.classes/src/test/resources/simplelogger.properties
new file mode 100644
index 00000000..92ba7a58
--- /dev/null
+++ 
b/org.apache.sling.feature.analyser.classes/src/test/resources/simplelogger.properties
@@ -0,0 +1 @@
+org.slf4j.simpleLogger.log.org.apache.sling.feature.analyser.task.classes.impl.CheckProviderTypeImplementations=debug
\ No newline at end of file

Reply via email to