This is an automated email from the ASF dual-hosted git repository.
jbonofre pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/karaf.git
The following commit(s) were added to refs/heads/main by this push:
new 5e4167f6ee fix(karaf-maven-plugin): Deal with non-features classifier
in the karaf-maven-plugin (#2521)
5e4167f6ee is described below
commit 5e4167f6ee4b3902f9d7f97ae96089516d02aab3
Author: JB Onofré <[email protected]>
AuthorDate: Wed Apr 15 23:49:40 2026 +0200
fix(karaf-maven-plugin): Deal with non-features classifier in the
karaf-maven-plugin (#2521)
---
.../tooling/features/GenerateDescriptorMojo.java | 32 +++++++++++++++++-----
.../karaf/tooling/utils/Dependency31Helper.java | 32 +++++++++++++++++++++-
2 files changed, 56 insertions(+), 8 deletions(-)
diff --git
a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/GenerateDescriptorMojo.java
b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/GenerateDescriptorMojo.java
index 684c2527e9..0f8c386205 100644
---
a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/GenerateDescriptorMojo.java
+++
b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/GenerateDescriptorMojo.java
@@ -26,9 +26,11 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
@@ -37,6 +39,7 @@ import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLStreamException;
import org.apache.karaf.features.internal.model.*;
+import org.apache.karaf.tooling.utils.Dependency31Helper;
import org.apache.karaf.tooling.utils.DependencyHelper;
import org.apache.karaf.tooling.utils.DependencyHelperFactory;
import org.apache.karaf.tooling.utils.LocalDependency;
@@ -490,6 +493,7 @@ public class GenerateDescriptorMojo extends MojoSupport {
// TODO Initialise the repositories from the existing feature file if
any
Map<Dependency, Feature> otherFeatures = new HashMap<>();
Map<Feature, String> featureRepositories = new HashMap<>();
+ Set<Object> recognizedFeatures = new HashSet<>();
FeaturesCache cache = new FeaturesCache(featuresCacheSize,
artifactCacheSize);
for (final LocalDependency entry : localDependencies) {
Object artifact = entry.getArtifact();
@@ -499,7 +503,7 @@ public class GenerateDescriptorMojo extends MojoSupport {
}
processFeatureArtifact(features, feature, otherFeatures,
featureRepositories, cache, artifact,
- entry.getParent(), true);
+ entry.getParent(), true, recognizedFeatures);
}
// Do not retain cache beyond this point
cache = null;
@@ -514,7 +518,7 @@ public class GenerateDescriptorMojo extends MojoSupport {
continue;
}
- if (!this.dependencyHelper.isArtifactAFeature(artifact)) {
+ if (!this.dependencyHelper.isArtifactAFeature(artifact) &&
!recognizedFeatures.contains(artifact)) {
String bundleName =
this.dependencyHelper.artifactToMvn(artifact,
getVersionOrRange(entry.getParent(), artifact));
for (ConfigFile cf : feature.getConfigfile()) {
@@ -609,11 +613,25 @@ public class GenerateDescriptorMojo extends MojoSupport {
private void processFeatureArtifact(Features features, Feature feature,
Map<Dependency, Feature> otherFeatures,
Map<Feature, String>
featureRepositories, FeaturesCache cache,
- Object artifact, Object parent,
boolean add)
+ Object artifact, Object parent,
boolean add, Set<Object> recognizedFeatures)
throws MojoExecutionException, XMLStreamException, JAXBException,
IOException {
- if (this.dependencyHelper.isArtifactAFeature(artifact) &&
FEATURE_CLASSIFIER.equals(
- this.dependencyHelper.getClassifier(artifact))) {
- File featuresFile = this.dependencyHelper.resolve(artifact,
getLog());
+ boolean isFeature = this.dependencyHelper.isArtifactAFeature(artifact);
+ File featuresFile = null;
+ if (!isFeature) {
+ // For XML artifacts with non-standard classifiers, resolve and
check content
+ featuresFile = this.dependencyHelper.resolve(artifact, getLog());
+ if (featuresFile != null && featuresFile.exists()
+ && Dependency31Helper.isFeaturesXml(featuresFile)) {
+ isFeature = true;
+ }
+ }
+ if (isFeature) {
+ if (recognizedFeatures != null) {
+ recognizedFeatures.add(artifact);
+ }
+ if (featuresFile == null) {
+ featuresFile = this.dependencyHelper.resolve(artifact,
getLog());
+ }
if (featuresFile == null || !featuresFile.exists()) {
throw new MojoExecutionException(
"Cannot locate file for feature: " + artifact + " at "
+ featuresFile);
@@ -621,7 +639,7 @@ public class GenerateDescriptorMojo extends MojoSupport {
Features includedFeatures = cache.getFeature(featuresFile);
for (String repository : includedFeatures.getRepository()) {
processFeatureArtifact(features, feature, otherFeatures,
featureRepositories, cache,
- cache.getArtifact(repository), parent, false);
+ cache.getArtifact(repository), parent, false,
recognizedFeatures);
}
for (Feature includedFeature : includedFeatures.getFeature()) {
Dependency dependency = new
Dependency(includedFeature.getName(), includedFeature.getVersion());
diff --git
a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/Dependency31Helper.java
b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/Dependency31Helper.java
index 44bd3d0fa2..497a8e7465 100644
---
a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/Dependency31Helper.java
+++
b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/Dependency31Helper.java
@@ -43,10 +43,16 @@ import org.eclipse.aether.util.graph.transformer.*;
import org.codehaus.plexus.util.StringUtils;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
import static java.lang.String.*;
import static org.apache.commons.lang3.reflect.MethodUtils.invokeMethod;
import static
org.apache.karaf.deployer.kar.KarArtifactInstaller.FEATURE_CLASSIFIER;
@@ -284,7 +290,31 @@ public class Dependency31Helper implements
DependencyHelper {
}
public static boolean isFeature(Artifact artifact) {
- return artifact.getExtension().equals("kar") ||
FEATURE_CLASSIFIER.equals(artifact.getClassifier());
+ if (artifact.getExtension().equals("kar") ||
FEATURE_CLASSIFIER.equals(artifact.getClassifier())) {
+ return true;
+ }
+ // For XML artifacts with non-standard classifiers, check actual
content when the file is available
+ if ("xml".equals(artifact.getExtension()) && artifact.getFile() !=
null && artifact.getFile().exists()) {
+ return isFeaturesXml(artifact.getFile());
+ }
+ return false;
+ }
+
+ public static boolean isFeaturesXml(File file) {
+ try (InputStream is = new FileInputStream(file)) {
+ XMLInputFactory xif = XMLInputFactory.newFactory();
+ xif.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true);
+ xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
+ xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES,
false);
+ XMLStreamReader r = xif.createXMLStreamReader(is);
+ r.nextTag();
+ QName name = r.getName();
+ return name.getLocalPart().equals("features")
+ && (name.getNamespaceURI().isEmpty()
+ ||
name.getNamespaceURI().startsWith("http://karaf.apache.org/xmlns/features/"));
+ } catch (Exception e) {
+ return false;
+ }
}
@Override