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

pengzheng pushed a commit to branch feature/556-osgi-uninstall
in repository https://gitbox.apache.org/repos/asf/celix.git

commit e62f269fa946f09aa54500d83e654d6f3698ca08
Author: PengZheng <[email protected]>
AuthorDate: Tue May 16 22:02:48 2023 +0800

    Add celix_bundleCache_destroyArchive to support OSGi uninstall.
    
    And some unit tests for bundle cache are added.
---
 libs/error_injector/CMakeLists.txt                 |  1 +
 libs/error_injector/celix_hash_map/CMakeLists.txt  | 25 ++++++++
 .../celix_hash_map/include/celix_hash_map_ei.h     | 34 ++++++++++
 .../celix_hash_map/src/celix_hash_map_ei.cc        | 29 +++++++++
 libs/framework/gtest/CMakeLists.txt                |  2 +
 .../src/CelixBundleCacheErrorInjectionTestSuite.cc | 60 ++++++++++++++++++
 libs/framework/src/bundle_archive.c                | 16 ++---
 libs/framework/src/celix_bundle_cache.c            | 74 ++++++++++++++--------
 libs/framework/src/celix_bundle_cache.h            | 11 ++++
 libs/framework/src/framework.c                     |  9 +--
 10 files changed, 216 insertions(+), 45 deletions(-)

diff --git a/libs/error_injector/CMakeLists.txt 
b/libs/error_injector/CMakeLists.txt
index 1607671e..bdf096fe 100644
--- a/libs/error_injector/CMakeLists.txt
+++ b/libs/error_injector/CMakeLists.txt
@@ -44,6 +44,7 @@ add_subdirectory(celix_log_helper)
 add_subdirectory(celix_bundle)
 add_subdirectory(celix_version)
 add_subdirectory(dfi)
+add_subdirectory(celix_hash_map)
 
 celix_subproject(ERROR_INJECTOR_MDNSRESPONDER "Option to enable building the 
mdnsresponder error injector" OFF)
 if (ERROR_INJECTOR_MDNSRESPONDER)
diff --git a/libs/error_injector/celix_hash_map/CMakeLists.txt 
b/libs/error_injector/celix_hash_map/CMakeLists.txt
new file mode 100644
index 00000000..dbef2bb6
--- /dev/null
+++ b/libs/error_injector/celix_hash_map/CMakeLists.txt
@@ -0,0 +1,25 @@
+# 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.
+
+add_library(hash_map_ei STATIC src/celix_hash_map_ei.cc)
+
+target_include_directories(hash_map_ei PUBLIC 
${CMAKE_CURRENT_LIST_DIR}/include)
+target_link_libraries(hash_map_ei PUBLIC Celix::error_injector Celix::utils)
+target_link_options(hash_map_ei INTERFACE
+        LINKER:--wrap,celix_stringHashMap_create
+)
+add_library(Celix::hash_map_ei ALIAS hash_map_ei)
diff --git a/libs/error_injector/celix_hash_map/include/celix_hash_map_ei.h 
b/libs/error_injector/celix_hash_map/include/celix_hash_map_ei.h
new file mode 100644
index 00000000..3c38ad41
--- /dev/null
+++ b/libs/error_injector/celix_hash_map/include/celix_hash_map_ei.h
@@ -0,0 +1,34 @@
+/*
+ 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.
+ */
+
+#ifndef CELIX_CELIX_HASH_MAP_EI_H
+#define CELIX_CELIX_HASH_MAP_EI_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "celix_string_hash_map.h"
+#include "celix_error_injector.h"
+
+CELIX_EI_DECLARE(celix_stringHashMap_create, celix_string_hash_map_t*);
+
+#ifdef __cplusplus
+}
+#endif
+#endif //CELIX_CELIX_HASH_MAP_EI_H
diff --git a/libs/error_injector/celix_hash_map/src/celix_hash_map_ei.cc 
b/libs/error_injector/celix_hash_map/src/celix_hash_map_ei.cc
new file mode 100644
index 00000000..4edbc381
--- /dev/null
+++ b/libs/error_injector/celix_hash_map/src/celix_hash_map_ei.cc
@@ -0,0 +1,29 @@
+/*
+ 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.
+ */
+
+#include "celix_hash_map_ei.h"
+
+extern "C" {
+celix_string_hash_map_t* __real_celix_stringHashMap_create();
+CELIX_EI_DEFINE(celix_stringHashMap_create, celix_string_hash_map_t*);
+celix_string_hash_map_t* __wrap_celix_stringHashMap_create() {
+    CELIX_EI_IMPL(celix_stringHashMap_create);
+    return __real_celix_stringHashMap_create();
+}
+}
diff --git a/libs/framework/gtest/CMakeLists.txt 
b/libs/framework/gtest/CMakeLists.txt
index c05fe4f5..e71fd953 100644
--- a/libs/framework/gtest/CMakeLists.txt
+++ b/libs/framework/gtest/CMakeLists.txt
@@ -127,6 +127,7 @@ if (LINKER_WRAP_SUPPORTED)
             src/BundleArchiveWithErrorInjectionTestSuite.cc
             src/CelixFrameworkUtilsErrorInjectionTestSuite.cc
             src/CelixBundleContextBundlesWithErrorTestSuite.cc
+            src/CelixBundleCacheErrorInjectionTestSuite.cc
     )
     target_compile_definitions(test_framework_with_ei PRIVATE
             SIMPLE_TEST_BUNDLE1_LOCATION="${SIMPLE_TEST_BUNDLE1}"
@@ -142,6 +143,7 @@ if (LINKER_WRAP_SUPPORTED)
             Celix::utils_ei
             Celix::asprintf_ei
             Celix::dlfcn_ei
+            Celix::hash_map_ei
             GTest::gtest GTest::gtest_main
     )
 
diff --git 
a/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc 
b/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc
new file mode 100644
index 00000000..dd181972
--- /dev/null
+++ b/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc
@@ -0,0 +1,60 @@
+/*
+ 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.
+ */
+
+#include "asprintf_ei.h"
+#include "celix_constants.h"
+#include "celix_bundle_cache.h"
+#include "celix_properties.h"
+#include "celix_log.h"
+#include "framework_private.h"
+#include "gtest/gtest.h"
+#include "celix_hash_map_ei.h"
+#include "malloc_ei.h"
+
+class CelixBundleCacheErrorInjectionTestSuite : public ::testing::Test {
+public:
+    CelixBundleCacheErrorInjectionTestSuite() {
+        fw.configurationMap = celix_properties_create();
+        fw.logger = celix_frameworkLogger_create(CELIX_LOG_LEVEL_TRACE);
+    }
+
+    ~CelixBundleCacheErrorInjectionTestSuite() override {
+        celix_ei_expect_asprintf(nullptr, 0, -1);
+        celix_ei_expect_celix_stringHashMap_create(nullptr, 0, nullptr);
+        celix_ei_expect_calloc(nullptr, 0, nullptr);
+        celix_frameworkLogger_destroy(fw.logger);
+        celix_properties_destroy(fw.configurationMap);
+    }
+    struct celix_framework fw{};
+};
+
+TEST_F(CelixBundleCacheErrorInjectionTestSuite, CacheCreateErrorTest) {
+    celix_bundle_cache_t *cache = nullptr;
+    celix_ei_expect_calloc((void *) celix_bundleCache_create, 0, nullptr);
+    EXPECT_EQ(CELIX_ENOMEM, celix_bundleCache_create(&fw, &cache));
+    EXPECT_EQ(nullptr, cache);
+    celix_ei_expect_celix_stringHashMap_create((void *) 
celix_bundleCache_create, 0, nullptr);
+    EXPECT_EQ(CELIX_ENOMEM, celix_bundleCache_create(&fw, &cache));
+    EXPECT_EQ(nullptr, cache);
+    celix_properties_setBool(fw.configurationMap, 
CELIX_FRAMEWORK_CACHE_USE_TMP_DIR, true);
+    celix_ei_expect_asprintf((void *) celix_bundleCache_create, 0, -1);
+    EXPECT_EQ(CELIX_ENOMEM, celix_bundleCache_create(&fw, &cache));
+    EXPECT_EQ(nullptr, cache);
+    celix_properties_setBool(fw.configurationMap, 
CELIX_FRAMEWORK_CACHE_USE_TMP_DIR, false);
+}
\ No newline at end of file
diff --git a/libs/framework/src/bundle_archive.c 
b/libs/framework/src/bundle_archive.c
index b06300b8..2fa5ab7e 100644
--- a/libs/framework/src/bundle_archive.c
+++ b/libs/framework/src/bundle_archive.c
@@ -461,18 +461,12 @@ celix_status_t bundleArchive_close(bundle_archive_pt 
archive) {
 }
 
 celix_status_t bundleArchive_closeAndDelete(bundle_archive_pt archive) {
-       celix_status_t status = CELIX_SUCCESS;
-
-       status = bundleArchive_close(archive);
-       if (status == CELIX_SUCCESS) {
-               const char* err = NULL;
-               status = celix_utils_deleteDirectory(archive->archiveRoot, 
&err);
-               framework_logIfError(archive->fw->logger, status, NULL, "Failed 
to delete archive root '%s': %s", archive->archiveRoot, err);
-       }
-
-       framework_logIfError(archive->fw->logger, status, NULL, "Failed to 
close and delete archive");
+    celix_status_t status = CELIX_SUCCESS;
 
-       return status;
+    const char* err = NULL;
+    status = celix_utils_deleteDirectory(archive->archiveRoot, &err);
+    framework_logIfError(archive->fw->logger, status, NULL, "Failed to delete 
archive root '%s': %s", archive->archiveRoot, err);
+    return status;
 }
 
 const char* celix_bundleArchive_getPersistentStoreRoot(bundle_archive_t* 
archive) {
diff --git a/libs/framework/src/celix_bundle_cache.c 
b/libs/framework/src/celix_bundle_cache.c
index c315164a..1b52a00f 100644
--- a/libs/framework/src/celix_bundle_cache.c
+++ b/libs/framework/src/celix_bundle_cache.c
@@ -54,6 +54,8 @@ struct celix_bundle_cache {
     celix_string_hash_map_t* locationToBundleIdLookupMap; //key = location, 
value = bundle id.
 };
 
+static void 
celix_bundleCache_updateIdForLocationLookupMap(celix_bundle_cache_t* cache);
+
 static const char* bundleCache_progamName() {
 #if defined(__APPLE__) || defined(__FreeBSD__)
        return getprogname();
@@ -118,14 +120,18 @@ celix_status_t 
celix_bundleCache_create(celix_framework_t* fw, celix_bundle_cach
     celix_bundle_cache_t *cache = calloc(1, sizeof(*cache));
     if (!cache) {
         status = CELIX_ENOMEM;
-        fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Cannot create 
bundle cache, out of memory");
-        return status;
+        goto cache_calloc_failure;
     }
 
+    cache->fw = fw;
     bool useTmpDir = celix_bundleCache_useTmpDir(fw);
     cache->deleteOnCreate = celix_bundleCache_cleanOnCreate(fw);
     cache->deleteOnDestroy = useTmpDir; //if tmp dir is used, delete on destroy
     cache->locationToBundleIdLookupMap = celix_stringHashMap_create();
+    if (NULL == cache->locationToBundleIdLookupMap) {
+        status = CELIX_ENOMEM;
+        goto cache_map_failure;
+    }
     celixThreadMutex_create(&cache->mutex, NULL);
 
     if (useTmpDir) {
@@ -135,12 +141,15 @@ celix_status_t 
celix_bundleCache_create(celix_framework_t* fw, celix_bundle_cach
         if (pg == NULL) {
             pg = "";
         }
-
         asprintf(&cache->cacheDir, "/tmp/celix-cache-%s-%s", pg, 
celix_framework_getUUID(fw));
     } else {
         const char* cacheDir = celix_bundleCache_cacheDirPath(fw);
         cache->cacheDir = celix_utils_strdup(cacheDir);
     }
+    if (NULL == cache->cacheDir) {
+        status = CELIX_ENOMEM;
+        goto cache_dir_failure;
+    }
 
     if (cache->deleteOnCreate) {
         status = celix_bundleCache_deleteCacheDir(cache);
@@ -157,9 +166,16 @@ celix_status_t celix_bundleCache_create(celix_framework_t* 
fw, celix_bundle_cach
         celix_bundleCache_destroy(cache);
         return status;
     }
-
+    celix_bundleCache_updateIdForLocationLookupMap(cache);
     *out = cache;
-       return status;
+    return CELIX_SUCCESS;
+cache_dir_failure:
+    celixThreadMutex_destroy(&cache->mutex);
+    celix_stringHashMap_destroy(cache->locationToBundleIdLookupMap);
+cache_map_failure:
+    free(cache);
+cache_calloc_failure:
+    return status;
 }
 
 celix_status_t celix_bundleCache_destroy(celix_bundle_cache_t* cache) {
@@ -178,6 +194,9 @@ celix_status_t 
celix_bundleCache_deleteCacheDir(celix_bundle_cache_t* cache) {
     const char* err = NULL;
     celixThreadMutex_lock(&cache->mutex);
     celix_status_t status = celix_utils_deleteDirectory(cache->cacheDir, &err);
+    if (status == CELIX_SUCCESS) {
+        celix_stringHashMap_clear(cache->locationToBundleIdLookupMap);
+    }
     celixThreadMutex_unlock(&cache->mutex);
     if (status != CELIX_SUCCESS) {
         fw_logCode(cache->fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Cannot 
delete bundle cache directory %s: %s", cache->cacheDir, err);
@@ -194,6 +213,9 @@ celix_status_t 
celix_bundleCache_createArchive(celix_framework_t* fw, long id, c
     if (archiveRoot) {
         celixThreadMutex_lock(&fw->cache->mutex);
         status = celix_bundleArchive_create(fw, archiveRoot, id, location, 
&archive);
+        if (status == CELIX_SUCCESS) {
+            celix_stringHashMap_put(fw->cache->locationToBundleIdLookupMap, 
location, (void*)id);
+        }
         celixThreadMutex_unlock(&fw->cache->mutex);
         celix_utils_freeStringIfNotEqual(archiveRootBuffer, archiveRoot);
     } else {
@@ -203,12 +225,6 @@ celix_status_t 
celix_bundleCache_createArchive(celix_framework_t* fw, long id, c
         fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Failed to 
create archive.");
         return status;
     }
-
-    //add bundle id and location to lookup maps
-    celixThreadMutex_lock(&fw->cache->mutex);
-    celix_stringHashMap_put(fw->cache->locationToBundleIdLookupMap, location, 
(void*)id);
-    celixThreadMutex_unlock(&fw->cache->mutex);
-
     *archiveOut = archive;
     return status;
 }
@@ -217,16 +233,28 @@ celix_status_t 
celix_bundleCache_createSystemArchive(celix_framework_t* fw, bund
     return celix_bundleCache_createArchive(fw, CELIX_FRAMEWORK_BUNDLE_ID, 
NULL, archive);
 }
 
+celix_status_t  celix_bundleCache_destroyArchive(celix_bundle_cache_t *cache, 
bundle_archive_pt archive) {
+    celix_status_t  status = CELIX_SUCCESS;
+    const char* loc = NULL;
+    celixThreadMutex_lock(&cache->mutex);
+    (void)bundleArchive_getLocation(archive, &loc);
+    (void)celix_stringHashMap_remove(cache->locationToBundleIdLookupMap, loc);
+    status = bundleArchive_closeAndDelete(archive);
+    celixThreadMutex_unlock(&cache->mutex);
+    (void)bundleArchive_destroy(archive);
+    return status;
+}
+
 /**
  * Update location->bundle id lookup map.
  * Assumes that bundle cache dir are not removed, so only adding not removing 
entries.
  */
-static void celix_bundleCache_updateIdForLocationLookupMap(celix_framework_t* 
fw) {
-    celixThreadMutex_lock(&fw->cache->mutex);
-    DIR* dir = opendir(fw->cache->cacheDir);
+static void 
celix_bundleCache_updateIdForLocationLookupMap(celix_bundle_cache_t* cache) {
+    celixThreadMutex_lock(&cache->mutex);
+    DIR* dir = opendir(cache->cacheDir);
     if (dir == NULL) {
-        fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, CELIX_BUNDLE_EXCEPTION, 
"Cannot open bundle cache directory %s", fw->cache->cacheDir);
-        celixThreadMutex_unlock(&fw->cache->mutex);
+        fw_logCode(cache->fw->logger, CELIX_LOG_LEVEL_ERROR, 
CELIX_BUNDLE_EXCEPTION, "Cannot open bundle cache directory %s", 
cache->cacheDir);
+        celixThreadMutex_unlock(&cache->mutex);
         return;
     }
     char archiveRootBuffer[CELIX_DEFAULT_STRING_CREATE_BUFFER_SIZE];
@@ -236,22 +264,22 @@ static void 
celix_bundleCache_updateIdForLocationLookupMap(celix_framework_t* fw
             continue;
         }
         char *bundleStateProperties = 
celix_utils_writeOrCreateString(archiveRootBuffer, sizeof(archiveRootBuffer),
-                                                                      
"%s/%s/%s", fw->cache->cacheDir, dent->d_name,
+                                                                      
"%s/%s/%s", cache->cacheDir, dent->d_name,
                                                                       
CELIX_BUNDLE_ARCHIVE_STATE_PROPERTIES_FILE_NAME);
         if (celix_utils_fileExists(bundleStateProperties)) {
             celix_properties_t *props = 
celix_properties_load(bundleStateProperties);
             const char *visitLoc = celix_properties_get(props, 
CELIX_BUNDLE_ARCHIVE_LOCATION_PROPERTY_NAME, NULL);
             long bndId = celix_properties_getAsLong(props, 
CELIX_BUNDLE_ARCHIVE_BUNDLE_ID_PROPERTY_NAME, -1);
             if (visitLoc != NULL && bndId >= 0) {
-                fw_log(fw->logger, CELIX_LOG_LEVEL_TRACE, "Adding location %s 
-> bnd id %li to lookup map",
+                fw_log(cache->fw->logger, CELIX_LOG_LEVEL_TRACE, "Adding 
location %s -> bnd id %li to lookup map",
                        visitLoc, bndId);
-                
celix_stringHashMap_putLong(fw->cache->locationToBundleIdLookupMap, visitLoc, 
bndId);
+                
celix_stringHashMap_putLong(cache->locationToBundleIdLookupMap, visitLoc, 
bndId);
             }
             celix_properties_destroy(props);
         }
     }
     closedir(dir);
-    celixThreadMutex_unlock(&fw->cache->mutex);
+    celixThreadMutex_unlock(&cache->mutex);
 }
 
 long celix_bundleCache_findBundleIdForLocation(celix_framework_t *fw, const 
char *location) {
@@ -261,12 +289,6 @@ long 
celix_bundleCache_findBundleIdForLocation(celix_framework_t *fw, const char
         bndId = 
celix_stringHashMap_getLong(fw->cache->locationToBundleIdLookupMap, location, 
-1);
     }
     celixThreadMutex_unlock(&fw->cache->mutex);
-    if (bndId == -1) {
-        celix_bundleCache_updateIdForLocationLookupMap(fw);
-        celixThreadMutex_lock(&fw->cache->mutex);
-        bndId = 
celix_stringHashMap_getLong(fw->cache->locationToBundleIdLookupMap, location, 
-1);
-        celixThreadMutex_unlock(&fw->cache->mutex);
-    }
     return bndId;
 }
 
diff --git a/libs/framework/src/celix_bundle_cache.h 
b/libs/framework/src/celix_bundle_cache.h
index e1829044..06810b54 100644
--- a/libs/framework/src/celix_bundle_cache.h
+++ b/libs/framework/src/celix_bundle_cache.h
@@ -87,6 +87,17 @@ celix_bundleCache_createArchive(celix_framework_t *fw, long 
id, const char *loca
  */
 celix_status_t celix_bundleCache_createSystemArchive(celix_framework_t* fw, 
bundle_archive_pt *archive);
 
+/**
+ * @brief Destroy the archive from the cache.
+ * It releases all resources allocated in celix_bundleCache_createArchive and 
deletes the archive directory.
+ * @param [in] cache The bundle cache to destroy archive from.
+ * @param [in] archive The archive to destroy.
+ * @return Status code indication failure or success:
+ *      - CELIX_SUCCESS when no errors are encountered.
+ *      - CELIX_FILE_IO_EXCEPTION when root of the archive is not a directory.
+ *      - errno when the directory cannot be deleted for other reasons, check 
error codes of fts_open/fts_read/remove.
+ */
+celix_status_t  celix_bundleCache_destroyArchive(celix_bundle_cache_t *cache, 
bundle_archive_pt archive);
 
 /**
  * @brief Deletes the entire bundle cache.
diff --git a/libs/framework/src/framework.c b/libs/framework/src/framework.c
index 44662850..8e9dd886 100644
--- a/libs/framework/src/framework.c
+++ b/libs/framework/src/framework.c
@@ -654,14 +654,7 @@ celix_status_t 
celix_framework_installBundleInternal(celix_framework_t *framewor
         long id = alreadyExistingBndId == -1 ? 
framework_getNextBundleId(framework) : alreadyExistingBndId;
         bundle_archive_t* archive = NULL;
         status = CELIX_DO_IF(status, 
celix_bundleCache_createArchive(framework, id, bndLoc, &archive));
-        if (status != CELIX_SUCCESS) {
-            bundleArchive_destroy(archive);
-        }
-
-        if (status == CELIX_SUCCESS) {
-            status = celix_bundle_createFromArchive(framework, archive, 
&bundle);
-        }
-
+        status = CELIX_DO_IF(status, celix_bundle_createFromArchive(framework, 
archive, &bundle));
         if (status == CELIX_SUCCESS) {
             celix_framework_bundle_entry_t *bEntry = 
fw_bundleEntry_create(bundle);
             celix_framework_bundleEntry_increaseUseCount(bEntry);

Reply via email to