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

jbonofre pushed a commit to branch karaf-4.4.x
in repository https://gitbox.apache.org/repos/asf/karaf.git


The following commit(s) were added to refs/heads/karaf-4.4.x by this push:
     new 36236aaeac fix(karaf-maven-plugin): handle KAR files in 
features-generate-descriptor (#2577)
36236aaeac is described below

commit 36236aaeac97e076dd3ce91ec31b32cf87e138a5
Author: JB Onofré <[email protected]>
AuthorDate: Fri Apr 24 16:27:00 2026 +0200

    fix(karaf-maven-plugin): handle KAR files in features-generate-descriptor 
(#2577)
    
    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 f49fe33ed7..b3f6f77db8 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