How does one launch a run configuration from code?

140 views
Skip to first unread message

Dave

unread,
Mar 17, 2015, 4:18:56 PM3/17/15
to bndtool...@googlegroups.com
Based on https://groups.google.com/forum/#!starred/bndtools-users/DVO-XzVs4oc, I tried the following:

        Workspace workspace = new Workspace(new File("/Users/dhumeniuk/git/myworkspace"));

        File projectDir = new File(workspace.getBase(), "myproject.integration");

        m_Run = new Run(workspace, projectDir, new File(projectDir, "launch.bndrun"));

        m_Run.getProjectLauncher().launch();

However, the project launcher is not able to find the framework bundle and in the end I get this message:

Exception in thread "main" java.lang.NoClassDefFoundError: org/osgi/framework/ServiceListener

at java.lang.ClassLoader.defineClass1(Native Method)

at java.lang.ClassLoader.defineClass(ClassLoader.java:800)

at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)

at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)

at java.net.URLClassLoader.access$100(URLClassLoader.java:71)

at java.net.URLClassLoader$1.run(URLClassLoader.java:361)

at java.net.URLClassLoader$1.run(URLClassLoader.java:355)

at java.security.AccessController.doPrivileged(Native Method)

at java.net.URLClassLoader.findClass(URLClassLoader.java:354)

at java.lang.ClassLoader.loadClass(ClassLoader.java:425)

at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)

at java.lang.ClassLoader.loadClass(ClassLoader.java:358)

at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:482)

Looking at the code, the workspace object has the correct base directory, but it only has a JPM4J bundle repo, it doesn't have the other bundle repositories, specifically the run repo that has the framework bundle.

Peter Kriens

unread,
Mar 19, 2015, 12:44:52 PM3/19/15
to bndtool...@googlegroups.com
On 17 mrt. 2015, at 21:18, Dave <dhum...@gmail.com> wrote:

Based on https://groups.google.com/forum/#!starred/bndtools-users/DVO-XzVs4oc, I tried the following:

        Workspace workspace = new Workspace(new File("/Users/dhumeniuk/git/myworkspace"));

Never ever use new File !!!! Use IO.getFile( "~/git/myworkspace"). This works on Windows AND Mac AND Linux.
Anyway. You got the wrong directory, in the constructor you need to specify the 'cnf' directory's file. Better use:

Workspace workspace = Workspace.getWorkspace(IO.getFile( "~/git/myworkspace"));

        File projectDir = new File(workspace.getBase(), "myproject.integration");

Use workspace.getFile("myproject.integration"). Uses IO under the covers (you can always specify absolute paths as well, and always with the forward slash).

Anyway, isn't this just:

Project myproject = Workspace.getProject("~/git/myworkspace/myproject.integration");

       m_Run = new Run(workspace, projectDir, new File(projectDir, "launch.bndrun"));
And

m_Run = new Run(workspace, project.getBase(), project.getFile("launch.bndrun");

        m_Run.getProjectLauncher().launch();

However, the project launcher is not able to find the framework bundle and in the end I get this message:

Since your workspace pointed to your workspace directory instead of the cnf directory you probably did not get your repositories. Ergo, you could not find the framework. The exception is since despite this error the launcher is started and then misses some key classes.

Some further hints:

Project & Workspace.isValid
Project.setTrace(true)
Project.setExceptions(true)
Project.isOk()

The exception philosophy in bnd is that exceptions are for punishing stupid bnd developers, they rarely are used to report user errors. These errors are reported in Project & Workspace. They are both Processor's that have getErrors(), getWarnings(), and isOk() or check() for testing.

In your case, you should have asked the Workspace if it was isValid, same for the project. You likely would have found the error(s) in Workspace.getErrors() or Workspace.getWarnings().

Hope this helps, kind regards,

Peter Kriens



Exception in thread "main" java.lang.NoClassDefFoundError: org/osgi/framework/ServiceListener

at java.lang.ClassLoader.defineClass1(Native Method)

at java.lang.ClassLoader.defineClass(ClassLoader.java:800)

at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)

at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)

at java.net.URLClassLoader.access$100(URLClassLoader.java:71)

at java.net.URLClassLoader$1.run(URLClassLoader.java:361)

at java.net.URLClassLoader$1.run(URLClassLoader.java:355)

at java.security.AccessController.doPrivileged(Native Method)

at java.net.URLClassLoader.findClass(URLClassLoader.java:354)

at java.lang.ClassLoader.loadClass(ClassLoader.java:425)

at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)

at java.lang.ClassLoader.loadClass(ClassLoader.java:358)


at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:482)

Looking at the code, the workspace object has the correct base directory, but it only has a JPM4J bundle repo, it doesn't have the other bundle repositories, specifically the run repo that has the framework bundle.


--
You received this message because you are subscribed to the Google Groups "bndtools-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bndtools-user...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Dave

unread,
Mar 19, 2015, 4:30:57 PM3/19/15
to bndtool...@googlegroups.com
It looks like the same generated/fw folder is used for each bndrun in the same project as well as the test launcher ?? Is there a way to specify the folder used so if I have the test launch a framework that they use different folders. Or is the thought that I would need to create a separate project for a framework to launch?

Dave

unread,
Mar 20, 2015, 10:41:30 AM3/20/15
to bndtool...@googlegroups.com
Okay, something is off. I've tried the following and none work:

// believe this was the suggestion as getWorkspace accepts the base workspace, not the cnf/build dir
Workspace workspace = Workspace.getWorkspace(IO.getFile( "~/git/workspace"));

assertThat(workspace.isValid(), is(true));

// tried this too, but the getWorkspace call fails and says no workspace found
Workspace workspace = Workspace.getWorkspace(IO.getFile( "~/git/workspace/cnf"));
assertThat(workspace.isValid(), is(true));

// figure I would let bnd find the workspace for me (BTW, is there a good way to get the current workspace that code is being executed from, ~/git/workspace will not be the same for everyone after all)
Workspace workspace = Workspace.findWorkspace(new File(TestRemoteClient.class.getProtectionDomain().getCodeSource().getLocation().toURI()));
assertThat(workspace.isValid(), is(true));


I gotta figure isValid is not correct given this test, it attempts to get the build.bnd from the base directory. shouldn't it be getting it from cnf/build.bnd from the base instead?

Thanks,
Dave

Dave

unread,
Mar 20, 2015, 10:52:45 AM3/20/15
to bndtool...@googlegroups.com
Also, if I ignore Workspace.isValid, and create the project, the valid, ok checks for the project object pass.

Dave

unread,
Mar 20, 2015, 10:55:30 AM3/20/15
to bndtool...@googlegroups.com
One more note: With the project object return true for isValid and isOk. I run:

        m_Run = new Run(workspace, myproject.getBase(), myproject.getFile("controller.bndrun"));

        assertThat(m_Run.isValid(), is(true));

        assertThat(m_Run.isOk(), is(true));

        m_Run.getProjectLauncher().launch();

m_Run isValid and isOk return true, but launch call still fails with the same class loader issue.

Dave

unread,
Mar 20, 2015, 2:34:08 PM3/20/15
to bndtool...@googlegroups.com
Figure this issue part out. Found the -runstorage property to change the directory.

Still haven't found a way to launch the configuration from code though.

Peter Kriens

unread,
Mar 24, 2015, 11:11:09 AM3/24/15
to bndtool...@googlegroups.com

Dave

unread,
Mar 30, 2015, 3:26:08 PM3/30/15
to bndtool...@googlegroups.com
I looked at it and tried to simplify my code by using the project launcher instead of a Run object. I am able to launch a project if I run the code outside of an OSGi environment. I'm trying to run integration tests (within OSGi environment) that require other OSGi frameworks to be started. For instance, so that I can test sending data between 2 OSGi frameworks. Does the bnd support launching another OSGi environment from an OSGi environment?

Thanks,
Dave

Peter Kriens

unread,
Mar 31, 2015, 12:12:23 PM3/31/15
to bndtool...@googlegroups.com
You just create new frameworks in your test … OSGi is 100% static free so you can run OSGi in OSGi, in OSGi, in OSGi until you run out of memory.

Kind regards,

Peter Kriens

Dave

unread,
Mar 31, 2015, 1:19:50 PM3/31/15
to bndtool...@googlegroups.com
Do you have any ideas on debugging my problem them. I looked at the example code and am still getting the error:

Exception in thread "main" java.lang.NoClassDefFoundError: org/osgi/framework/ServiceListener

at java.lang.ClassLoader.defineClass1(Native Method)

at java.lang.ClassLoader.defineClass(ClassLoader.java:800)

at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)

at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)

at java.net.URLClassLoader.access$100(URLClassLoader.java:71)

at java.net.URLClassLoader$1.run(URLClassLoader.java:361)

at java.net.URLClassLoader$1.run(URLClassLoader.java:355)

at java.security.AccessController.doPrivileged(Native Method)

at java.net.URLClassLoader.findClass(URLClassLoader.java:354)

at java.lang.ClassLoader.loadClass(ClassLoader.java:425)

at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)

at java.lang.ClassLoader.loadClass(ClassLoader.java:358)

at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:482)


For some reason my local repositories are not showing as available.

Dave

unread,
Mar 31, 2015, 3:05:38 PM3/31/15
to bndtool...@googlegroups.com
I created an example Github repository that produces the same error when running https://github.com/dhumeniuk/bnd-launcher-example/blob/master/example.integration/src/example/integration/ExampleTest.java using the Bnd test launcher. Hopefully this will help to debug the issue.

Peter Kriens

unread,
Apr 2, 2015, 4:34:29 AM4/2/15
to bndtool...@googlegroups.com
There were a couple of things wrong with your code.

There was I think a confusion between OSGi launch, OSGi Run and normal JUnit. Your test method was written as a plain JUnit test but it was in the src folder, not the test folder. This caused it to be both the test AND the bundle to be tested. Since the bundle now contained test code, it had an import on JUnit that the framework could not provide so it failed.

I moved the test method to ’test’ (and setup test source folder to output to ’bin_test’ and added a HelloWorld class in ’src’.  So now I had a simple test and a clean bundle. The test method now worked from JUnit. Well, it ran the Hello World after adding an Bundle-Activator header.

So this makes the basics work. However, it is not clear to me what you actually want to do? 

JUNit test -> run a bundle from a workspace
JUnit test -> run a test from a workspace
OSGi Run -> run a bundle from a workspace
OSGi Run -> run a test from a workspace
OSGi Test -> run a bundle from a workspace?
OSGi Test -> run a test from a workspace?

In the current code it looks like you want to reuse the parent and the child which, if it had been setup correctly, would have created an infinite launch loop …

Kind regards,

Peter Kriens



Dave

unread,
Apr 2, 2015, 9:46:43 AM4/2/15
to bndtool...@googlegroups.com
From your options, I would say I want to do "OSGi Test -> run a test from a workspace" where the tests spins up another OSGi framework.

That was just an example, so I'm okay with the infinite loop. Really, I would actually want to reference a bndrun file in the same project, but I was trying to start simple and just reuse the project run bundles. I guess I'm not sure what you mean by the method being written as a plain JUnit test, but the intention was for the test method to run as an integration test in an OSGi environment using the Bnd OSGi test launcher, not using the JUnit test runner or Bnd OSGi run launcher. That's why I wanted it in the src folder with an import for JUnit (at least that is my understanding as where source goes for integration tests).

I'm able to get this to work as a JUnit test, but that doesn't get me what I need. You can use the JUnit runner from the source bundle, but ultimately I want to write an integration test that spins up another OSGi framework (call it system B), have the integration test invoke a service in the system under test (call it system A, the on that also has an integration test bundle), the service on system A communicates with system B through a socket and I verify that my remote socket bundle (installed on systems A and B) works as expected.

Thanks,
Dave

Peter Kriens

unread,
Apr 2, 2015, 10:38:40 AM4/2/15
to bndtool...@googlegroups.com
So then you don’t need a launcher, you need a tester … Suggest you first get it to work step by step. First start with JUnit and an normal OSGi run, then from JUnit a bnd test run (see Project.test()), and then OSGi Bndrun -> test, and then OSGi Bnd test -> test. One step at the time …


Kind regards,

Peter Kriens




Reply all
Reply to author
Forward
0 new messages