[ 
https://issues.apache.org/jira/browse/KARAF-5395?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16194431#comment-16194431
 ] 

Guillaume Nodet commented on KARAF-5395:
----------------------------------------

I think I have a real fix now.
The below patch bypasses the region mechanism when there is a single region. 
The effect is that all resources are merged.
{code}
diff --git 
a/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java
 
b/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java
index 33b9dae6e3..4b512e4c0e 100644
--- 
a/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java
+++ 
b/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java
@@ -365,9 +365,10 @@ public class Subsystem extends ResourceImpl {
                                 Set<String> overrides,
                                 String featureResolutionRange,
                                 final String serviceRequirements,
-                                RepositoryManager repos) throws Exception {
+                                RepositoryManager repos,
+                                boolean bypassRegions) throws Exception {
         for (Subsystem child : children) {
-            child.downloadBundles(manager, overrides, featureResolutionRange, 
serviceRequirements, repos);
+            child.downloadBundles(manager, overrides, featureResolutionRange, 
serviceRequirements, repos, bypassRegions);
         }
         final Map<String, ResourceImpl> bundles = new ConcurrentHashMap<>();
         final Downloader downloader = manager.createDownloader();
@@ -445,11 +446,18 @@ public class Subsystem extends ResourceImpl {
                 final Conditional cond = entry.getValue();
                 ResourceImpl res = bundles.get(loc);
                 int sl = bi.getStartLevel() <= 0 ? feature.getStartLevel() : 
bi.getStartLevel();
-                if (bi.isDependency()) {
-                    addDependency(res, false, bi.isStart(), sl);
-                } else {
-                    doAddDependency(res, cond == null, bi.isStart(), sl);
+                boolean mandatory = !bi.isDependency() && cond == null;
+                Subsystem where = this;
+                if (bypassRegions) {
+                    while (where.parent != null) {
+                        where = where.parent;
+                    }
+                } else if (bi.isDependency()) {
+                    while (!where.acceptDependencies) {
+                        where = where.parent;
+                    }
                 }
+                where.doAddDependency(res, mandatory, bi.isStart(), sl);
                 if (cond != null) {
                     addIdentityRequirement(res, resConds.get(cond), true);
                 }
diff --git 
a/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolver.java
 
b/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolver.java
index d9ec573191..caf31067de 100644
--- 
a/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolver.java
+++ 
b/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolver.java
@@ -86,6 +86,8 @@ public class SubsystemResolver {
     private RegionDigraph flatDigraph;
     private Map<String, Map<String, BundleInfo>> bundleInfos;
 
+    private boolean bypassRegions;
+
     public SubsystemResolver(Resolver resolver, DownloadManager manager) {
         this.resolver = resolver;
         this.manager = manager;
@@ -115,6 +117,7 @@ public class SubsystemResolver {
         if (root == null) {
             return;
         }
+        bypassRegions = root.getChildren().isEmpty();
 
         // Pre-resolve
         root.build(allFeatures);
@@ -184,7 +187,7 @@ public class SubsystemResolver {
 
         // Download bundles
         RepositoryManager repos = new RepositoryManager();
-        root.downloadBundles(manager, overrides, featureResolutionRange, 
serviceRequirements, repos);
+        root.downloadBundles(manager, overrides, featureResolutionRange, 
serviceRequirements, repos, bypassRegions);
 
         // Populate digraph and resolve
         digraph = new StandardRegionDigraph(null, null);
{code}

> ResourceImpl/RequirementImpl/CapabilityImpl do not correctly implement their 
> OSGi interface contracts
> -----------------------------------------------------------------------------------------------------
>
>                 Key: KARAF-5395
>                 URL: https://issues.apache.org/jira/browse/KARAF-5395
>             Project: Karaf
>          Issue Type: Bug
>          Components: karaf-feature
>    Affects Versions: 4.2.0, 4.1.2, 4.0.10
>            Reporter: Robert Varga
>            Assignee: Guillaume Nodet
>            Priority: Critical
>
> This is a follow-up of downstream issue tracked at 
> https://bugs.opendaylight.org/show_bug.cgi?id=9218.
> OpenDaylight uses auto-generated features, which may end up packaging a 
> bundle multiple times in separate features -- which can be regarded as a bug, 
> but it certainly is counter-intuitive.
> Using a simple test case of wanting to install all features at the same time 
> triggers huge memory usage spike in Felix Resolver.
> Since ResourceImpl does not explictly override hashCode()/equals() according 
> to org.osgi.resource.Resource interface contract, every resource declaration 
> in a feature is treated as unique -- disregarding the fact that multiple 
> bundle declarations are actually pointing to the same bundle.
> This cascades to both RequirementImpl and CapabilityImpl, hence each such 
> duplicate bundle is added to the set of Requirements to be resolved and its 
> capabilities are added to potential candidates -- leading to Felix Resolver 
> having a large problem space (what to resolve) and also having a large 
> solution space (how to resolve) -- leading to polynomial explosion in CPU and 
> memory requirements.
> The amount of memory consumed by OpenDaylight Nitrogen RC3 has been observed 
> at 1.2GB, e.g. with a heap smaller than that, the container runs into OOM 
> during feature:install before actual installation starts.



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to