NanoContainer
  1. NanoContainer
  2. NANO-181

BeanShell doesn't propagate classloader correctly.

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: core
    • Labels:
      None
    • Number of attachments :
      0

      Description

      Original Text of the message From Mailing List

      >
      >
      > I took a look into it and at first it looked like the simple fix would
      > be to change BeanShellContainerBuilder.createContainerFromScript() to:
      >
      >
      >
      > Interpreter i = new Interpreter();
      >
      > try

      { > > i.set("parent", parentContainer); > > i.set("assemblyScope", assemblyScope); > > i.setClassLoader(this.getClassLoader()); > > i.eval(getScriptReader(), i.getNameSpace(), > "nanocontainer.bsh"); > > return (PicoContainer) i.get("pico"); > > }

      catch (EvalError e)

      { > > throw new NanoContainerMarkupException(e); > > } catch (IOException e) {> > throw new NanoContainerMarkupException(e);> > }

      >
      >
      >
      >
      >
      > (The line I added was in bold).
      >
      >
      >
      > I have verified in a test case that the classloader into the
      > interpreter is getting set properly. But the following test case
      > fails: (Originally added to BeanShellContainerBuilderTestCase)
      >
      >
      >
      > public void
      > testWithParentClassPathPropagatesWithToBeanShellInterpreter()throws
      > IOException {
      >
      > Reader script = new StringReader("" +
      >
      > "try

      {\n" + > > " Class.forName(\"TestComp\");\n" + > > "}

      catch (ClassNotFoundException ex)

      {\n" + > > " ClassLoader current = this.getClass().getClassLoader > (); \n" + > > " print(current.toString());\n" + //1 > > " print(current.getParent().toString());\n" + > > > "}

      \n" +
      >
      >
      >
      > "pico = new
      > org.nanocontainer.reflection.DefaultNanoPicoContainer(parent);\n" +
      >
      > "pico.registerComponentImplementation( TestComp );
      > \n");
      >
      >
      >
      > File testCompJar = new File(System.getProperty
      > ("testcomp.jar"));
      >
      > URLClassLoader classLoader = new URLClassLoader(new URL[]
      >

      {testCompJar.toURL()}

      , this.getClass().getClassLoader());
      >
      > Class testComp = null;
      >
      > PicoContainer parent = new DefaultPicoContainer();
      >
      >
      >
      > try

      { > > testComp = classLoader.loadClass("TestComp"); //2 > > }

      catch (ClassNotFoundException ex)

      { > > fail("Unable to load test component from the jar using a > url classloader"); > > }

      >
      >
      >
      > PicoContainer pico = buildContainer(new
      > BeanShellContainerBuilder(script, classLoader), parent, "SOME_SCOPE");
      >
      > assertNotNull(pico);
      >
      > Object testCompInstance = pico.getComponentInstance
      > (testComp.getName());
      >
      > assertEquals(testCompInstance.getClass().getName(),
      > testComp.getName());
      >
      >
      >
      > }
      >
      >
      >
      >
      >
      > The tempComp loads properly, as shown in the code at comment #2. But
      > the beanshell script portion in blue fails to load TestComp and the
      > ClassLoader printout shows:
      >
      >
      >
      > sun.misc.Launcher$AppClassLoader@a39137
      >
      > sun.misc.Launcher$ExtClassLoader@92e78c
      >
      >
      >
      > Which if things were working properly, there should be a
      > URLClassLoader in the first line instead of AppClassLoader.
      >
      >
      >
      >
      >
      >
      >
      > Since this evening was my first foray into work with BeanShell, and I
      > can verify by debug stepping that the proper classloader is now (with
      > the one line added) getting properly passed into the BeanShell
      > interpreter, I'm not quite sure what to say.
      >
      >
      >
      > Is this a bug in BeanShell? Have you had custom classloader success
      > in BeanShell otherwise??
      >
      >
      >
      > Could someone with more BeanShell success take a look at the
      > situation?
      >
      >
      >
      > Sorry I couldn't further assist you.
      >
      Hi Mike,

      Your assistance and the last hint solved the problem. The 2.0b1 version of the BeanShell exhibits the classloader problem. So I downloaded the
      2.0b4 version, manually installed it in my local mvn repo and with your changes to the BeanShellContainerBuilder.createContainerFromScript() my OSGi application now works fine.

      BTW I ended going with the smaller bsh-core.jar versus the bsh.jar to reduce the size by 135K.

        Activity

        Hide
        Michael Rimov added a comment -

        The test case for this:

        BeanShellContainerBuilderTestCase.testWithParentClassPathPropagatesWithToBeanShellInterpreter() will pass with BeanShell 2.0b4. However, 2.0B4 is currently only available for Maven2.

        Mauro has filed a request to have this version included to Maven 1 repositories as well:

        http://jira.codehaus.org/browse/MAVENUPLOAD-951

        Officially the bug is fixed, but I'm going to leave it open as a reminder to re-enable the test case as soon as the updated beanshell is available.

        Show
        Michael Rimov added a comment - The test case for this: BeanShellContainerBuilderTestCase.testWithParentClassPathPropagatesWithToBeanShellInterpreter() will pass with BeanShell 2.0b4. However, 2.0B4 is currently only available for Maven2. Mauro has filed a request to have this version included to Maven 1 repositories as well: http://jira.codehaus.org/browse/MAVENUPLOAD-951 Officially the bug is fixed, but I'm going to leave it open as a reminder to re-enable the test case as soon as the updated beanshell is available.
        Michael Rimov made changes -
        Field Original Value New Value
        Description Original Text of the message From Mailing List Original Text of the message From Mailing List


        >
        >
        > I took a look into it and at first it looked like the simple fix would
        > be to change BeanShellContainerBuilder.createContainerFromScript() to:
        >
        >
        >
        > Interpreter i = new Interpreter();
        >
        > try {
        >
        > i.set("parent", parentContainer);
        >
        > i.set("assemblyScope", assemblyScope);
        >
        > i.setClassLoader(this.getClassLoader());
        >
        > i.eval(getScriptReader(), i.getNameSpace(),
        > "nanocontainer.bsh");
        >
        > return (PicoContainer) i.get("pico");
        >
        > } catch (EvalError e) {
        >
        > throw new NanoContainerMarkupException(e);
        >
        > } catch (IOException e) {
        >
        > throw new NanoContainerMarkupException(e);
        >
        > }
        >
        >
        >
        >
        >
        > (The line I added was in bold).
        >
        >
        >
        > I have verified in a test case that the classloader into the
        > interpreter is getting set properly. But the following test case
        > fails: (Originally added to BeanShellContainerBuilderTestCase)
        >
        >
        >
        > public void
        > testWithParentClassPathPropagatesWithToBeanShellInterpreter()throws
        > IOException {
        >
        > Reader script = new StringReader("" +
        >
        > "try {\n" +
        >
        > " Class.forName(\"TestComp\");\n" +
        >
        > "} catch (ClassNotFoundException ex) {\n" +
        >
        > " ClassLoader current = this.getClass().getClassLoader
        > (); \n" +
        >
        > " print(current.toString());\n" + //1
        >
        > " print(current.getParent().toString());\n" +
        >
        >
        > "}\n" +
        >
        >
        >
        > "pico = new
        > org.nanocontainer.reflection.DefaultNanoPicoContainer(parent);\n" +
        >
        > "pico.registerComponentImplementation( TestComp );
        > \n");
        >
        >
        >
        > File testCompJar = new File(System.getProperty
        > ("testcomp.jar"));
        >
        > URLClassLoader classLoader = new URLClassLoader(new URL[]
        > {testCompJar.toURL()}, this.getClass().getClassLoader());
        >
        > Class testComp = null;
        >
        > PicoContainer parent = new DefaultPicoContainer();
        >
        >
        >
        > try {
        >
        > testComp = classLoader.loadClass("TestComp"); //2
        >
        > } catch (ClassNotFoundException ex) {
        >
        > fail("Unable to load test component from the jar using a
        > url classloader");
        >
        > }
        >
        >
        >
        > PicoContainer pico = buildContainer(new
        > BeanShellContainerBuilder(script, classLoader), parent, "SOME_SCOPE");
        >
        > assertNotNull(pico);
        >
        > Object testCompInstance = pico.getComponentInstance
        > (testComp.getName());
        >
        > assertEquals(testCompInstance.getClass().getName(),
        > testComp.getName());
        >
        >
        >
        > }
        >
        >
        >
        >
        >
        > The tempComp loads properly, as shown in the code at comment #2. But
        > the beanshell script portion in blue fails to load TestComp and the
        > ClassLoader printout shows:
        >
        >
        >
        > sun.misc.Launcher$AppClassLoader@a39137
        >
        > sun.misc.Launcher$ExtClassLoader@92e78c
        >
        >
        >
        > Which if things were working properly, there should be a
        > URLClassLoader in the first line instead of AppClassLoader.
        >
        >
        >
        > :-(
        >
        >
        >
        > Since this evening was my first foray into work with BeanShell, and I
        > can verify by debug stepping that the proper classloader is now (with
        > the one line added) getting properly passed into the BeanShell
        > interpreter, I'm not quite sure what to say.
        >
        >
        >
        > Is this a bug in BeanShell? Have you had custom classloader success
        > in BeanShell otherwise??
        >
        >
        >
        > Could someone with more BeanShell success take a look at the
        > situation?
        >
        >
        >
        > Sorry I couldn't further assist you.
        >
        Hi Mike,

        Your assistance and the last hint solved the problem. The 2.0b1 version of the BeanShell exhibits the classloader problem. So I downloaded the
        2.0b4 version, manually installed it in my local mvn repo and with your changes to the BeanShellContainerBuilder.createContainerFromScript() my OSGi application now works fine.

        BTW I ended going with the smaller bsh-core.jar versus the bsh.jar to reduce the size by 135K.

        Hide
        Michael Rimov added a comment -

        Just read Jörg's, commens on NanoREMOTING05 I realize – Leave the test out of Maven 1

        Thanks Jörg!

        Show
        Michael Rimov added a comment - Just read Jörg's, commens on NanoREMOTING05 I realize – Leave the test out of Maven 1 Thanks Jörg!
        Michael Rimov made changes -
        Status Open [ 1 ] Closed [ 6 ]
        Resolution Fixed [ 1 ]

          People

          • Assignee:
            Unassigned
            Reporter:
            Michael Rimov
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: