You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2019/10/02 18:46:32 UTC
[celix] 01/02: gh-80: Adds exception check and handle for bundle
start
This is an automated email from the ASF dual-hosted git repository.
pnoltes pushed a commit to branch feature/#80_bundle_start_with_exception
in repository https://gitbox.apache.org/repos/asf/celix.git
commit 87c387ad03eb4004f79300af514131f107f60804
Author: Pepijn Noltes <pe...@gmail.com>
AuthorDate: Tue Oct 1 20:11:18 2019 +0200
gh-80: Adds exception check and handle for bundle start
---
cmake/Modules/FindCUnit.cmake | 65 ----------------------
libs/framework/include/celix_bundle_context.h | 5 +-
libs/framework/include/celix_framework.h | 27 +++++++++
libs/framework/private/mock/bundle_context_mock.c | 3 +-
libs/framework/private/mock/framework_mock.c | 3 +-
libs/framework/src/bundle_context.c | 8 +--
libs/framework/src/framework.c | 16 ++++--
libs/framework/src/framework_private.h | 2 -
libs/framework/tst/CMakeLists.txt | 3 +-
.../framework/tst/bundle_context_bundles_tests.cpp | 12 ++++
libs/framework/tst/nop_activator.c | 35 ++++++++++++
11 files changed, 95 insertions(+), 84 deletions(-)
diff --git a/cmake/Modules/FindCUnit.cmake b/cmake/Modules/FindCUnit.cmake
deleted file mode 100644
index 830f551..0000000
--- a/cmake/Modules/FindCUnit.cmake
+++ /dev/null
@@ -1,65 +0,0 @@
-# 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.
-
-if (NOT WIN32)
- include(FindCurses)
-endif (NOT WIN32)
-
-FIND_PATH(CUNIT_INCLUDE_DIR CUnit/Basic.h
- /usr/local/include
- /usr/include
- /opt/local/include
-)
-
-FIND_PATH(CUNIT_SHARE_DIR CUnit-List.dtd
- /usr/local/share/Cunit
- /usr/share/CUnit
- /opt/local/share/CUnit
-)
-
-# On unix system, debug and release have the same name
-FIND_LIBRARY(CUNIT_LIBRARY cunit
- ${CUNIT_INCLUDE_DIR}/../../lib
- /usr/local/lib
- /usr/lib
- )
-FIND_LIBRARY(CUNIT_DEBUG_LIBRARY cunit
- ${CUNIT_INCLUDE_DIR}/../../lib
- /usr/local/lib
- /usr/lib
- )
-
-IF(CUNIT_INCLUDE_DIR)
- IF(CUNIT_LIBRARY)
- SET(CUNIT_FOUND "YES")
- if (WIN32)
- SET(CUNIT_LIBRARIES ${CUNIT_LIBRARY})
- SET(CUNIT_DEBUG_LIBRARIES ${CUNIT_DEBUG_LIBRARY})
- else (WIN32)
- SET(CUNIT_LIBRARIES ${CUNIT_LIBRARY} ${CURSES_LIBRARY})
- SET(CUNIT_DEBUG_LIBRARIES ${CUNIT_DEBUG_LIBRARY} ${CURSES_DEBUG_LIBRARY})
- endif (WIN32)
- ENDIF(CUNIT_LIBRARY)
- IF(CUNIT_INCLUDE_DIR)
- if (WIN32)
- SET(CUNIT_INCLUDE_DIRS ${CUNIT_INCLUDE_DIR})
- else (WIN32)
- MESSAGE(STATUS "Found CUNIT: ${CUNIT_INCLUDE_DIR}")
- SET(CUNIT_INCLUDE_DIRS ${CUNIT_INCLUDE_DIR} ${CURSES_INCLUDE_DIR})
- endif (WIN32)
- ENDIF(CUNIT_INCLUDE_DIR)
-ENDIF(CUNIT_INCLUDE_DIR)
diff --git a/libs/framework/include/celix_bundle_context.h b/libs/framework/include/celix_bundle_context.h
index 0c845a2..779c134 100644
--- a/libs/framework/include/celix_bundle_context.h
+++ b/libs/framework/include/celix_bundle_context.h
@@ -716,8 +716,9 @@ long celix_bundleContext_trackBundlesWithOptions(
* @param callbackHandle The data pointer, which will be used in the callbacks
* @param use The callback which will be called for the currently started bundles.
* The bundle pointers are only guaranteed to be valid during the callback.
+ * @return Returns true if the bundle is found and the callback is called.
*/
-void celix_bundleContext_useBundle(
+bool celix_bundleContext_useBundle(
celix_bundle_context_t *ctx,
long bundleId,
void *callbackHandle,
@@ -726,7 +727,7 @@ void celix_bundleContext_useBundle(
/**
* Use the currently active (started) bundles.
- * The provided callback will be called for all the currently started bundles.
+ * The provided callback will be called for all the currently started bundles (excluding the framework bundle).
*
* @param ctx The bundle context.
* @param callbackHandle The data pointer, which will be used in the callbacks
diff --git a/libs/framework/include/celix_framework.h b/libs/framework/include/celix_framework.h
index 76ebcb5..470de9b 100644
--- a/libs/framework/include/celix_framework.h
+++ b/libs/framework/include/celix_framework.h
@@ -50,6 +50,33 @@ celix_bundle_context_t* celix_framework_getFrameworkContext(const celix_framewor
*/
celix_bundle_t* celix_framework_getFrameworkBundle(const celix_framework_t *fw);
+/**
+ * Use the currently active (started) bundles.
+ * The provided callback will be called for all the currently started bundles.
+ *
+ * @param ctx The bundle context.
+ * @param includeFrameworkBundle If true the callback will also be triggered for the framework bundle.
+ * @param callbackHandle The data pointer, which will be used in the callbacks
+ * @param use The callback which will be called for the currently started bundles.
+ * The bundle pointers are only guaranteed to be valid during the callback.
+ */
+void celix_framework_useBundles(celix_framework_t *fw, bool includeFrameworkBundle, void *callbackHandle, void(*use)(void *handle, const celix_bundle_t *bnd));
+
+/**
+ * Use the bundle with the provided bundle id
+ * The provided callback will be called if the bundle is found.
+ *
+ * @param fw The framework.
+ * @param onlyActive If true only starting and active bundles will trigger the callback.
+ * @param bundleId The bundle id.
+ * @param callbackHandle The data pointer, which will be used in the callbacks
+ * @param use The callback which will be called for the currently started bundles.
+ * The bundle pointers are only guaranteed to be valid during the callback.
+ * @return Returns true if the bundle is found and the callback is called.
+ */
+bool celix_framework_useBundle(celix_framework_t *fw, bool onlyActive, long bndId, void *callbackHandle, void(*use)(void *handle, const celix_bundle_t *bnd));
+
+
#ifdef __cplusplus
}
diff --git a/libs/framework/private/mock/bundle_context_mock.c b/libs/framework/private/mock/bundle_context_mock.c
index 4dec7db..8644a1a 100644
--- a/libs/framework/private/mock/bundle_context_mock.c
+++ b/libs/framework/private/mock/bundle_context_mock.c
@@ -273,7 +273,7 @@ void celix_bundleContext_useBundles(
}
-void celix_bundleContext_useBundle(
+bool celix_bundleContext_useBundle(
bundle_context_t *ctx,
long bundleId,
void *callbackHandle,
@@ -283,6 +283,7 @@ void celix_bundleContext_useBundle(
->withLongIntParameters("bundleId", bundleId)
->withPointerParameters("callbackHandle", callbackHandle)
->withPointerParameters("use", use);
+ return mock_c()->returnValue().value.boolValue;
}
void celix_bundleContext_stopTracker(bundle_context_t *ctx, long trackerId) {
diff --git a/libs/framework/private/mock/framework_mock.c b/libs/framework/private/mock/framework_mock.c
index d651b94..8e49218 100644
--- a/libs/framework/private/mock/framework_mock.c
+++ b/libs/framework/private/mock/framework_mock.c
@@ -329,13 +329,14 @@ void celix_framework_useBundles(framework_t *fw, bool includeFrameworkBundle, vo
->withPointerParameters("use", use);
}
-void celix_framework_useBundle(framework_t *fw, bool onlyActive, long bundleId, void *callbackHandle, void(*use)(void *handle, const bundle_t *bnd)) {
+bool celix_framework_useBundle(framework_t *fw, bool onlyActive, long bundleId, void *callbackHandle, void(*use)(void *handle, const bundle_t *bnd)) {
mock_c()->actualCall("celix_framework_useBundle")
->withPointerParameters("fw", fw)
->withBoolParameters("onlyActive", onlyActive)
->withLongIntParameters("bundleId", bundleId)
->withPointerParameters("callbackHandle", callbackHandle)
->withPointerParameters("use", use);
+ return mock_c()->returnValue().value.boolValue;
}
service_registration_t* celix_framework_registerServiceFactory(framework_t *fw , const celix_bundle_t *bnd, const char* serviceName, celix_service_factory_t *factory, celix_properties_t *properties) {
diff --git a/libs/framework/src/bundle_context.c b/libs/framework/src/bundle_context.c
index 3098884..dd76ba1 100644
--- a/libs/framework/src/bundle_context.c
+++ b/libs/framework/src/bundle_context.c
@@ -602,12 +602,12 @@ void celix_bundleContext_useBundles(
celix_framework_useBundles(ctx->framework, false, callbackHandle, use);
}
-void celix_bundleContext_useBundle(
+bool celix_bundleContext_useBundle(
bundle_context_t *ctx,
long bundleId,
void *callbackHandle,
void (*use)(void *handle, const bundle_t *bundle)) {
- celix_framework_useBundle(ctx->framework, true, bundleId, callbackHandle, use);
+ return celix_framework_useBundle(ctx->framework, true, bundleId, callbackHandle, use);
}
static void bundleContext_cleanupBundleTrackers(bundle_context_t *ctx) {
@@ -690,10 +690,6 @@ long celix_bundleContext_installBundle(bundle_context_t *ctx, const char *bundle
status = bundle_getBundleId(bnd, &bundleId);
if (status == CELIX_SUCCESS && autoStart) {
status = bundle_start(bnd);
- if (status != CELIX_SUCCESS) {
- bundleId = -1;
- bundle_uninstall(bnd);
- }
}
}
diff --git a/libs/framework/src/framework.c b/libs/framework/src/framework.c
index 35f0cef..17d56f3 100644
--- a/libs/framework/src/framework.c
+++ b/libs/framework/src/framework.c
@@ -930,7 +930,6 @@ celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int opti
status = CELIX_ENOMEM;
} else {
void * userData = NULL;
- bundle_context_t *context;
create_function_fp create = (create_function_fp) celix_libloader_getSymbol((celix_library_handle_t*) bundle_getHandle(bundle), OSGI_FRAMEWORK_BUNDLE_ACTIVATOR_CREATE);
if (create == NULL) {
create = celix_libloader_getSymbol(bundle_getHandle(bundle), OSGI_FRAMEWORK_DEPRECATED_BUNDLE_ACTIVATOR_CREATE);
@@ -976,6 +975,11 @@ celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int opti
status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_ACTIVE));
status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STARTED, bundle));
+
+ if (status != CELIX_SUCCESS) {
+ //state is still STARTING, back to resolved
+ framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_RESOLVED);
+ }
}
}
@@ -986,7 +990,6 @@ celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int opti
fw_bundleEntry_decreaseUseCount(framework, bndId);
if (status != CELIX_SUCCESS) {
- module_pt module = NULL;
const char *symbolicName = NULL;
long id = 0;
bundle_getCurrentModule(bundle, &module);
@@ -997,9 +1000,6 @@ celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int opti
} else {
fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not start bundle: %s [%ld]", symbolicName, id);
}
- if(activator!=NULL){
- free(activator);
- }
}
return status;
@@ -2584,7 +2584,8 @@ void celix_framework_useBundles(framework_t *fw, bool includeFrameworkBundle, vo
celix_arrayList_destroy(bundleIds);
}
-void celix_framework_useBundle(framework_t *fw, bool onlyActive, long bundleId, void *callbackHandle, void(*use)(void *handle, const bundle_t *bnd)) {
+bool celix_framework_useBundle(framework_t *fw, bool onlyActive, long bundleId, void *callbackHandle, void(*use)(void *handle, const bundle_t *bnd)) {
+ bool called = false;
if (bundleId >= 0) {
fw_bundleEntry_increaseUseCount(fw, bundleId);
bundle_t *bnd = framework_getBundleById(fw, bundleId);
@@ -2592,14 +2593,17 @@ void celix_framework_useBundle(framework_t *fw, bool onlyActive, long bundleId,
celix_bundle_state_e bndState = celix_bundle_getState(bnd);
if (onlyActive && (bndState == OSGI_FRAMEWORK_BUNDLE_ACTIVE || bndState == OSGI_FRAMEWORK_BUNDLE_STARTING)) {
use(callbackHandle, bnd);
+ called = true;
} else if (!onlyActive) {
use(callbackHandle, bnd);
+ called = true;
}
} else {
framework_logIfError(fw->logger, CELIX_FRAMEWORK_EXCEPTION, NULL, "Bundle with id %li is not installed", bundleId);
}
fw_bundleEntry_decreaseUseCount(fw, bundleId);
}
+ return called;
}
service_registration_t* celix_framework_registerServiceFactory(framework_t *fw , const celix_bundle_t *bnd, const char* serviceName, celix_service_factory_t *factory, celix_properties_t *properties) {
diff --git a/libs/framework/src/framework_private.h b/libs/framework/src/framework_private.h
index 20dad52..6728ff7 100644
--- a/libs/framework/src/framework_private.h
+++ b/libs/framework/src/framework_private.h
@@ -153,8 +153,6 @@ FRAMEWORK_EXPORT bundle_pt framework_getBundleById(framework_pt framework, long
**********************************************************************************************************************
**********************************************************************************************************************/
-void celix_framework_useBundles(framework_t *fw, bool includeFrameworkBundle, void *callbackHandle, void(*use)(void *handle, const bundle_t *bnd));
-void celix_framework_useBundle(framework_t *fw, bool onlyActive, long bundleId, void *callbackHandle, void(*use)(void *handle, const bundle_t *bnd));
service_registration_t* celix_framework_registerServiceFactory(framework_t *fw , const celix_bundle_t *bnd, const char* serviceName, celix_service_factory_t *factory, celix_properties_t *properties);
#endif /* FRAMEWORK_PRIVATE_H_ */
diff --git a/libs/framework/tst/CMakeLists.txt b/libs/framework/tst/CMakeLists.txt
index efd919e..7ef1ceb 100644
--- a/libs/framework/tst/CMakeLists.txt
+++ b/libs/framework/tst/CMakeLists.txt
@@ -18,6 +18,7 @@
add_celix_bundle(simple_test_bundle1 NO_ACTIVATOR VERSION 1.0.0)
add_celix_bundle(simple_test_bundle2 NO_ACTIVATOR VERSION 1.0.0)
add_celix_bundle(simple_test_bundle3 NO_ACTIVATOR VERSION 1.0.0)
+add_celix_bundle(bundle_with_exception SOURCES nop_activator.c VERSION 1.0.0)
add_subdirectory(subdir) #simple_test_bundle4 and simeple_test_bundle5
add_executable(test_framework
@@ -30,7 +31,7 @@ add_executable(test_framework
)
target_link_libraries(test_framework Celix::framework ${CURL_LIBRARIES} ${CPPUTEST_LIBRARY})
-add_dependencies(test_framework simple_test_bundle1_bundle simple_test_bundle2_bundle simple_test_bundle3_bundle simple_test_bundle4_bundle simple_test_bundle5_bundle)
+add_dependencies(test_framework simple_test_bundle1_bundle simple_test_bundle2_bundle simple_test_bundle3_bundle simple_test_bundle4_bundle simple_test_bundle5_bundle bundle_with_exception)
target_include_directories(test_framework PRIVATE ../src)
configure_file(config.properties.in config.properties @ONLY)
diff --git a/libs/framework/tst/bundle_context_bundles_tests.cpp b/libs/framework/tst/bundle_context_bundles_tests.cpp
index 6887418..f193173 100644
--- a/libs/framework/tst/bundle_context_bundles_tests.cpp
+++ b/libs/framework/tst/bundle_context_bundles_tests.cpp
@@ -41,6 +41,7 @@ TEST_GROUP(CelixBundleContextBundlesTests) {
const char * const TEST_BND3_LOC = "simple_test_bundle3.zip";
const char * const TEST_BND4_LOC = "simple_test_bundle4.zip";
const char * const TEST_BND5_LOC = "simple_test_bundle5.zip";
+ const char * const TEST_BND_WITH_EXCEPTION_LOC = "bundle_with_exception.zip";
void setup() {
properties = properties_create();
@@ -90,6 +91,17 @@ TEST(CelixBundleContextBundlesTests, useBundlesTest) {
CHECK_EQUAL(1, count);
};
+TEST(CelixBundleContextBundlesTests, startBundleWithException) {
+ long bndId = celix_bundleContext_installBundle(ctx, TEST_BND_WITH_EXCEPTION_LOC, true);
+ CHECK(bndId > 0); //bundle is installed, but not started
+
+ bool called = celix_framework_useBundle(fw, false, bndId, nullptr, [](void */*handle*/, const celix_bundle_t *bnd) {
+ auto state = celix_bundle_getState(bnd);
+ CHECK_EQUAL(state, OSGI_FRAMEWORK_BUNDLE_RESOLVED);
+ });
+ CHECK_TRUE(called);
+}
+
TEST(CelixBundleContextBundlesTests, useBundleTest) {
int count = 0;
diff --git a/libs/framework/tst/nop_activator.c b/libs/framework/tst/nop_activator.c
new file mode 100644
index 0000000..ad2b57d
--- /dev/null
+++ b/libs/framework/tst/nop_activator.c
@@ -0,0 +1,35 @@
+/**
+ *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_api.h"
+
+struct bundle_act {
+
+};
+
+static celix_status_t act_start(struct bundle_act *act __attribute__((unused)), celix_bundle_context_t *ctx __attribute__((unused))) {
+ printf("Return a bundle 'exception'\n");
+ return CELIX_BUNDLE_EXCEPTION;
+}
+
+static celix_status_t act_stop(struct bundle_act *act __attribute__((unused)), celix_bundle_context_t *ctx __attribute__((unused))) {
+ return CELIX_SUCCESS;
+}
+
+CELIX_GEN_BUNDLE_ACTIVATOR(struct bundle_act, act_start, act_stop);
\ No newline at end of file