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 c98092e3f2 fix(karaf-maven-plugin): handle KAR files in 
features-generate-descriptor (#2578)
c98092e3f2 is described below

commit c98092e3f21d5e951ed65caf0102342086db464f
Author: JB Onofré <[email protected]>
AuthorDate: Fri Apr 24 14:29:15 2026 +0200

    fix(karaf-maven-plugin): handle KAR files in features-generate-descriptor 
(#2578)
    
    Commit 9afa6485c5 removed the FEATURE_CLASSIFIER guard in
    processFeatureArtifact, causing .kar artifacts to enter the feature
    processing branch. Since a KAR is a ZIP archive, JaxbUtil.unmarshal()
    failed with "Content is not allowed in prolog" when trying to parse it
    as raw XML.
    
    Fix readFeaturesFile() to detect .kar files and extract their embedded
    features XML entries from the repository/ directory inside the archive,
    merging them into a single Features object.
---
 .../tooling/features/GenerateDescriptorMojo.java   | 34 ++++++++++++++++++++++
 1 file changed, 34 insertions(+)

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 0f8c386205..2b70f6b8e4 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
@@ -22,6 +22,7 @@ import static 
org.apache.karaf.deployer.kar.KarArtifactInstaller.FEATURE_CLASSIF
 
 import java.io.*;
 import java.nio.file.Files;
+import java.util.zip.ZipEntry;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Comparator;
@@ -757,11 +758,44 @@ public class GenerateDescriptorMojo extends MojoSupport {
     static Features readFeaturesFile(File featuresFile) throws 
XMLStreamException, JAXBException, IOException {
         if (JacksonUtil.isJson(featuresFile.toURI().toASCIIString())) {
             return JacksonUtil.unmarshal(featuresFile.toURI().toASCIIString());
+        } else if (featuresFile.getName().endsWith(".kar")) {
+            return readFeaturesFromKar(featuresFile);
         } else {
             return JaxbUtil.unmarshal(featuresFile.toURI().toASCIIString(), 
false);
         }
     }
 
+    static Features readFeaturesFromKar(File karFile) throws IOException, 
XMLStreamException, JAXBException {
+        ObjectFactory objectFactory = new ObjectFactory();
+        Features merged = objectFactory.createFeaturesRoot();
+        merged.setName(karFile.getName());
+        try (JarInputStream jar = new JarInputStream(new 
FileInputStream(karFile))) {
+            ZipEntry entry;
+            while ((entry = jar.getNextEntry()) != null) {
+                String entryName = entry.getName();
+                if (!entry.isDirectory()
+                        && entryName.startsWith("repository/")
+                        && entryName.endsWith(".xml")
+                        && !new 
File(entryName).getName().startsWith("maven-metadata")) {
+                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                    byte[] buf = new byte[8192];
+                    int n;
+                    while ((n = jar.read(buf)) != -1) {
+                        baos.write(buf, 0, n);
+                    }
+                    try {
+                        Features f = JaxbUtil.unmarshal(entryName, new 
ByteArrayInputStream(baos.toByteArray()), false);
+                        merged.getFeature().addAll(f.getFeature());
+                        merged.getRepository().addAll(f.getRepository());
+                    } catch (Exception e) {
+                        // Not a features XML, skip
+                    }
+                }
+            }
+        }
+        return merged;
+    }
+
     @Override
     public void setLog(Log log) {
         this.log = log;

Reply via email to