From da0bbcbd30e23f93ceff089921f08111a80f459e Mon Sep 17 00:00:00 2001 From: christophd Date: Mon, 20 Feb 2017 11:09:52 +0100 Subject: [PATCH] #209 Improved Citrus initialization in order to be more flexible on classpath loading order of libs --- .../cucumber/runtime/java/CitrusBackend.java | 75 ++++++++++++------- 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/modules/citrus-cucumber/src/main/java/cucumber/runtime/java/CitrusBackend.java b/modules/citrus-cucumber/src/main/java/cucumber/runtime/java/CitrusBackend.java index d2a5d4646d..c7c2a75c99 100644 --- a/modules/citrus-cucumber/src/main/java/cucumber/runtime/java/CitrusBackend.java +++ b/modules/citrus-cucumber/src/main/java/cucumber/runtime/java/CitrusBackend.java @@ -44,16 +44,11 @@ public class CitrusBackend implements Backend { /** Citrus instance used by all scenarios */ private static Citrus citrus; + private static InitializationHook initializationHook; /** Basic resource loader */ private ResourceLoader resourceLoader; - /** Glue holding all step definitions */ - private Glue glue; - - /** Glue paths */ - private List gluePaths; - /** * Constructor using resource loader. * @param resourceLoader @@ -64,8 +59,11 @@ public CitrusBackend(ResourceLoader resourceLoader) { @Override public void loadGlue(Glue glue, List gluePaths) { - this.glue = glue; - this.gluePaths = gluePaths; + try { + initializationHook = new InitializationHook(glue, gluePaths, getObjectFactory()); + } catch (IllegalAccessException e) { + throw new CitrusRuntimeException("Failed to add XML step definition", e); + } try { if (!gluePaths.contains(CitrusLifecycleHooks.class.getPackage().getName()) && getObjectFactory().addClass(CitrusLifecycleHooks.class)) { @@ -88,23 +86,6 @@ public void setUnreportedStepExecutor(UnreportedStepExecutor executor) { @Override public void buildWorld() { - if (glue != null) { - getCitrus().beforeSuite(CitrusReporter.SUITE_NAME); - - for (String gluePath : gluePaths) { - ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"classpath*:" + gluePath.replaceAll("\\.", "/").replaceAll("^classpath:", "") + "/**/*Steps.xml"}, true, getCitrus().getApplicationContext()); - - try { - for (StepTemplate stepTemplate : ctx.getBeansOfType(StepTemplate.class).values()) { - glue.addStepDefinition(new XmlStepDefinition(stepTemplate, getObjectFactory())); - } - } catch (IllegalAccessException e) { - throw new CitrusRuntimeException("Failed to add XML step definition", e); - } - } - - glue = null; - } } @Override @@ -138,6 +119,10 @@ private ObjectFactory getObjectFactory() throws IllegalAccessException { public static Citrus getCitrus() { if (citrus == null) { citrus = Citrus.newInstance(); + + if (initializationHook != null) { + initializationHook.run(); + } } return citrus; @@ -154,6 +139,10 @@ public static void initializeCitrus(ApplicationContext applicationContext) { } citrus = Citrus.newInstance(applicationContext); + + if (initializationHook != null) { + initializationHook.run(); + } } /** @@ -163,4 +152,40 @@ public static void initializeCitrus(ApplicationContext applicationContext) { public static void resetCitrus() { citrus = null; } + + /** + * Initialization hook performs before suite actions and XML step initialization. Called as soon as citrus instance is requested + * from outside for the first time. Performs only once. + */ + private static class InitializationHook implements Runnable { + + private final Glue glue; + private final List gluePaths; + private final ObjectFactory objectFactory; + + private boolean performed = false; + + InitializationHook(Glue glue, List gluePaths, ObjectFactory objectFactory) { + this.glue = glue; + this.gluePaths = gluePaths; + this.objectFactory = objectFactory; + } + + @Override + public void run() { + if (!performed) { + getCitrus().beforeSuite(CitrusReporter.SUITE_NAME); + + for (String gluePath : gluePaths) { + ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"classpath*:" + gluePath.replaceAll("\\.", "/").replaceAll("^classpath:", "") + "/**/*Steps.xml"}, true, getCitrus().getApplicationContext()); + + for (StepTemplate stepTemplate : ctx.getBeansOfType(StepTemplate.class).values()) { + glue.addStepDefinition(new XmlStepDefinition(stepTemplate, objectFactory)); + } + } + + performed = true; + } + } + } }