JBehave
  1. JBehave
  2. JBEHAVE-368

Ensure same instance of EmbedderClassLoader is used to find and run stories from Ant or Maven

    Details

    • Type: Bug Bug
    • Status: Resolved Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.0.2
    • Fix Version/s: 3.1
    • Component/s: Ant Tasks, Maven Plugin
    • Labels:
      None
    • Environment:
      Maven 2.2.1 and JDK 1.6
    • Number of attachments :
      1

      Description

      I'm getting the following stacktrace when using the ServiceLoader infrastructure in my JBehave steps while running under the maven plugin. I think this is caused by using different class loaders to find the stories and then to execute them. It starts working if I patch createClassLoader in AbstractEmbedderMojo to cache the created classloader and to reuse that every time.

      java.lang.ClassCastException
      at java.lang.Class.cast(Class.java:2990)
      at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:345)
      at java.util.ServiceLoader$1.next(ServiceLoader.java:421)
      at com.salerio.idm.service.AdaptorsModule.configure(AdaptorsModule.java:33)
      at com.google.inject.AbstractModule.configure(AbstractModule.java:59)
      at com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:223)
      at com.google.inject.spi.Elements.getElements(Elements.java:101)
      at com.google.inject.InjectorShell$Builder.build(InjectorShell.java:135)
      at com.google.inject.InjectorBuilder.build(InjectorBuilder.java:102)
      at com.google.inject.Guice.createInjector(Guice.java:92)
      at com.google.inject.Guice.createInjector(Guice.java:69)
      at functional.BaseFixture.initializeInjector(BaseFixture.java:272)
      at functional.BaseFixture.initialize(BaseFixture.java:104)
      at bdd.FixedIncomeSteps.init(FixedIncomeSteps.java:36)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.jbehave.core.steps.StepCreator$BeforeOrAfter.run(StepCreator.java:348)
      at org.jbehave.core.steps.StepCreator$1.perform(StepCreator.java:74)
      at org.jbehave.core.embedder.StoryRunner$FineSoFar.run(StoryRunner.java:202)
      at org.jbehave.core.embedder.StoryRunner.runSteps(StoryRunner.java:187)
      at org.jbehave.core.embedder.StoryRunner.runStorySteps(StoryRunner.java:170)
      at org.jbehave.core.embedder.StoryRunner.run(StoryRunner.java:84)
      at org.jbehave.core.embedder.StoryRunner.run(StoryRunner.java:63)
      at org.jbehave.core.embedder.Embedder.runStoriesAsPaths(Embedder.java:194)
      at bdd.MyStories.run(MyStories.java:52)
      at org.jbehave.core.embedder.Embedder.runStoriesWithAnnotatedEmbedderRunner(Embedder.java:137)
      at org.jbehave.mojo.RunStoriesWithAnnotatedEmbedderRunner.execute(RunStoriesWithAnnotatedEmbedderRunner.java:20)
      at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:490)
      at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:694)
      at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:556)
      at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:535)
      at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:387)
      at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:348)
      at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180)
      at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
      at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
      at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
      at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
      at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
      at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
      at org.codehaus.classworlds.Launcher.main(Launcher.java:375)

      1. jb.patch
        0.9 kB
        Daniel Godfrey

        Activity

        Hide
        Paul Hammant added a comment -

        You're using Guice and the java.util ServiceLocator ?
        (please forgive me but they feel like the antithesis of each other)

        Can you show us a code fragment so we can reporduce?
        If it helps (and you have maven build capability), then you could modify the jbehave-trader-guice example to show us the root problem

        Show
        Paul Hammant added a comment - You're using Guice and the java.util ServiceLocator ? (please forgive me but they feel like the antithesis of each other) Can you show us a code fragment so we can reporduce? If it helps (and you have maven build capability), then you could modify the jbehave-trader-guice example to show us the root problem
        Hide
        Daniel Godfrey added a comment -

        Yup, java.util.ServiceLoader though, not ServiceLocator. It's being used to change the guice bindings, but only because of some tangled dependencies between jars that I've seen no need to fix. It has the benefit of allowing you to change the modules at runtime, by just changing the classpath.

        I'll have a look at the trader guice example, I have a patched local clone of the repo with the classloader caching fix I mentioned above, but not sure how I'll manage to work it in the example.

        Show
        Daniel Godfrey added a comment - Yup, java.util.ServiceLoader though, not ServiceLocator. It's being used to change the guice bindings, but only because of some tangled dependencies between jars that I've seen no need to fix. It has the benefit of allowing you to change the modules at runtime, by just changing the classpath. I'll have a look at the trader guice example, I have a patched local clone of the repo with the classloader caching fix I mentioned above, but not sure how I'll manage to work it in the example.
        Hide
        Mauro Talevi added a comment -

        If you want to attach the patch you have (command-line diff generated please) that would be a good starting point.

        What Paul was after was a way for us to reproduce the behaviour and verify that it's been fixed. If have another self-contained example (as simple as possible), that would be fine too.

        Show
        Mauro Talevi added a comment - If you want to attach the patch you have (command-line diff generated please) that would be a good starting point. What Paul was after was a way for us to reproduce the behaviour and verify that it's been fixed. If have another self-contained example (as simple as possible), that would be fine too.
        Hide
        Paul Hammant added a comment -

        My bad for misreading.

        How about just the patch you have (rather than alluding to it). That'll help get us on the same page.

        • Paul
        Show
        Paul Hammant added a comment - My bad for misreading. How about just the patch you have (rather than alluding to it). That'll help get us on the same page. Paul
        Hide
        Daniel Godfrey added a comment -

        Patch attached. I don't have diff installed, so it's generated with EclipseHg in git extended format.

        Show
        Daniel Godfrey added a comment - Patch attached. I don't have diff installed, so it's generated with EclipseHg in git extended format.
        Daniel Godfrey made changes -
        Field Original Value New Value
        Attachment jb.patch [ 51732 ]
        Mauro Talevi made changes -
        Summary ClassCastException while using java.util.ServiceLoader infrastructure in tests using maven plugin. Ensure same instance of EmbedderClassLoader is used to find and run stories from Ant or Maven
        Assignee Mauro Talevi [ maurotalevi ]
        Fix Version/s 3.1 [ 16511 ]
        Component/s Ant Tasks [ 11081 ]
        Mauro Talevi made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Resolution Fixed [ 1 ]
        Hide
        Mauro Talevi added a comment -

        Daniel, fix in 3.1-beta-2. Could you please try it out and let us know if it works on your build?

        Show
        Mauro Talevi added a comment - Daniel, fix in 3.1-beta-2. Could you please try it out and let us know if it works on your build?
        Hide
        Daniel Godfrey added a comment - - edited

        Yep, works fine thanks.

        Show
        Daniel Godfrey added a comment - - edited Yep, works fine thanks.

          People

          • Assignee:
            Mauro Talevi
            Reporter:
            Daniel Godfrey
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: