New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash when trying to acquire bundle context #172

Closed
cewee opened this Issue Nov 25, 2016 · 6 comments

Comments

Projects
3 participants
@cewee

cewee commented Nov 25, 2016

when executing the snippet from the documentation (uServices-bundlecontext) the executable crashes,
because the private ContextBundle part is NULL in GetBundleContext() . This happens on the developement branch.

@karthikreddy09

This comment has been minimized.

Show comment
Hide comment
@karthikreddy09

karthikreddy09 Nov 25, 2016

Contributor

I think the code in this snippet is based on v2.0 and needs to be updated for v3.0

Contributor

karthikreddy09 commented Nov 25, 2016

I think the code in this snippet is based on v2.0 and needs to be updated for v3.0

@saschazelzer

This comment has been minimized.

Show comment
Hide comment
@saschazelzer

saschazelzer Nov 25, 2016

Member

I believe the code is up-to-date with v3.0 but snippets were never required to actually run successfully. Originally, they were intended to be minimal compilable snippets of code.

If it does not inflate the snippet code, I'd say we should make them self-contained and hence executable. For others, we could probably just create an object file instead of an executable.

Member

saschazelzer commented Nov 25, 2016

I believe the code is up-to-date with v3.0 but snippets were never required to actually run successfully. Originally, they were intended to be minimal compilable snippets of code.

If it does not inflate the snippet code, I'd say we should make them self-contained and hence executable. For others, we could probably just create an object file instead of an executable.

@cewee

This comment has been minimized.

Show comment
Hide comment
@cewee

cewee Nov 25, 2016

I looked at the snippet as an example, because we're trying to integrate the dev branch into a project, and i wasn't able to perform obtain a successful GetBundleContext(), so I wondered what we missed.
Do you have a quick idea what could be missing here ?

cewee commented Nov 25, 2016

I looked at the snippet as an example, because we're trying to integrate the dev branch into a project, and i wasn't able to perform obtain a successful GetBundleContext(), so I wondered what we missed.
Do you have a quick idea what could be missing here ?

@saschazelzer

This comment has been minimized.

Show comment
Hide comment
@saschazelzer

saschazelzer Nov 25, 2016

Member
Member

saschazelzer commented Nov 25, 2016

@cewee

This comment has been minimized.

Show comment
Hide comment
@cewee

cewee Nov 25, 2016

I added a framework to the main like this, accessing the BundleContext works fine,
directly via the static GetBundleContext() does not.

#include "cppmicroservices/BundleInitialization.h"
CPPMICROSERVICES_INITIALIZE_BUNDLE
int main(int /*argc*/, char* /*argv*/[])
{
  FrameworkFactory ff;
  Framework fw = ff.NewFramework();
  fw.Start();

  // this works, output: system_bundle
  std::cout << fw.GetBundleContext().GetBundle(0).GetSymbolicName() << std::endl;

  // this does not work
  // returns a context, but the BundleContextPrivate object in the PIMPL is null
  auto context = GetBundleContext();
  auto bundle = context.GetBundle();
  std::cout << "Bundle name: " << bundle.GetSymbolicName() << " [id: " << bundle.GetBundleId() << "]\n";
  return 0;
}

Your help and hints are greatly appreciated!!

cewee commented Nov 25, 2016

I added a framework to the main like this, accessing the BundleContext works fine,
directly via the static GetBundleContext() does not.

#include "cppmicroservices/BundleInitialization.h"
CPPMICROSERVICES_INITIALIZE_BUNDLE
int main(int /*argc*/, char* /*argv*/[])
{
  FrameworkFactory ff;
  Framework fw = ff.NewFramework();
  fw.Start();

  // this works, output: system_bundle
  std::cout << fw.GetBundleContext().GetBundle(0).GetSymbolicName() << std::endl;

  // this does not work
  // returns a context, but the BundleContextPrivate object in the PIMPL is null
  auto context = GetBundleContext();
  auto bundle = context.GetBundle();
  std::cout << "Bundle name: " << bundle.GetSymbolicName() << " [id: " << bundle.GetBundleId() << "]\n";
  return 0;
}

Your help and hints are greatly appreciated!!

@saschazelzer

This comment has been minimized.

Show comment
Hide comment
@saschazelzer

saschazelzer Nov 28, 2016

Member

Basically, your executable is missing a manifest.json resource file. Using GetBundleContext() retrieves a context associated with the calling site`s bundle, but your executable does not provide a valid bundle (see doc)

In v3.0 (yet to be released), bundles are required to provide a manifest. Your case is special because an executable acting as a bundle container is treated slightly differently: all its (valid) bundles are installed automatically on framework initialization. If you are using CMake, you can add the missing pieces lke this:

set(_target main)
set(_bundle_name main)
set(_srcs main.cpp)
# Generate a custom "bundle init" file (remove any occurence of
# CPPMICROSERVICES_INITIALIZE_BUNDLE from your sources).
usFunctionGenerateBundleInit(_srcs)

# Track dependencies on resource files
usFunctionGetResourceSource(TARGET ${_target} OUT _srcs)
add_executable(${_target} ${_srcs})

# The US_BUNDLE_NAME compile definition is required
set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS US_BUNDLE_NAME=${_bundle_name})
set_property(TARGET ${_target} PROPERTY US_BUNDLE_NAME ${_bundle_name})

# Add the manifest file as a resource (assumes you have created a manifest.json file
# with e.g. "{ bundle.name : "main" }"
usFunctionEmbedResources(TARGET ${_target} FILES manifest.json)

target_link_libraries(${_target} CppMicroServices)

If you are not using CMake, you would basically need to call the usResourceCompiler executable manually, to embed the manifest.json into the binary.

Member

saschazelzer commented Nov 28, 2016

Basically, your executable is missing a manifest.json resource file. Using GetBundleContext() retrieves a context associated with the calling site`s bundle, but your executable does not provide a valid bundle (see doc)

In v3.0 (yet to be released), bundles are required to provide a manifest. Your case is special because an executable acting as a bundle container is treated slightly differently: all its (valid) bundles are installed automatically on framework initialization. If you are using CMake, you can add the missing pieces lke this:

set(_target main)
set(_bundle_name main)
set(_srcs main.cpp)
# Generate a custom "bundle init" file (remove any occurence of
# CPPMICROSERVICES_INITIALIZE_BUNDLE from your sources).
usFunctionGenerateBundleInit(_srcs)

# Track dependencies on resource files
usFunctionGetResourceSource(TARGET ${_target} OUT _srcs)
add_executable(${_target} ${_srcs})

# The US_BUNDLE_NAME compile definition is required
set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS US_BUNDLE_NAME=${_bundle_name})
set_property(TARGET ${_target} PROPERTY US_BUNDLE_NAME ${_bundle_name})

# Add the manifest file as a resource (assumes you have created a manifest.json file
# with e.g. "{ bundle.name : "main" }"
usFunctionEmbedResources(TARGET ${_target} FILES manifest.json)

target_link_libraries(${_target} CppMicroServices)

If you are not using CMake, you would basically need to call the usResourceCompiler executable manually, to embed the manifest.json into the binary.

@saschazelzer saschazelzer self-assigned this Feb 9, 2017

@saschazelzer saschazelzer added this to In Progress in Release 3.1 Feb 13, 2017

@saschazelzer saschazelzer added this to the Release 3.1 milestone Feb 13, 2017

@saschazelzer saschazelzer moved this from In Progress to Done in Release 3.1 Feb 13, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment