diff --git a/core/src/main/java/cucumber/runtime/NoInstancesException.java b/core/src/main/java/cucumber/runtime/NoInstancesException.java new file mode 100644 index 0000000000..152e545a6d --- /dev/null +++ b/core/src/main/java/cucumber/runtime/NoInstancesException.java @@ -0,0 +1,12 @@ +package cucumber.runtime; + +public class NoInstancesException extends CucumberException { + + public NoInstancesException(Class parentType) { + super(createMessage(parentType)); + } + + private static String createMessage(Class parentType) { + return String.format("Couldn't find a single implementation of " + parentType); + } +} diff --git a/core/src/main/java/cucumber/runtime/Reflections.java b/core/src/main/java/cucumber/runtime/Reflections.java index 6ee929a938..e060ebe8ff 100644 --- a/core/src/main/java/cucumber/runtime/Reflections.java +++ b/core/src/main/java/cucumber/runtime/Reflections.java @@ -16,9 +16,9 @@ public T instantiateExactlyOneSubclass(Class parentType, String packageNa if (instances.size() == 1) { return instances.iterator().next(); } else if (instances.size() == 0) { - throw new CucumberException("Couldn't find a single implementation of " + parentType); + throw new NoInstancesException(parentType); } else { - throw new CucumberException("Expected only one instance, but found too many: " + instances); + throw new TooManyInstancesException(instances); } } diff --git a/core/src/main/java/cucumber/runtime/TooManyInstancesException.java b/core/src/main/java/cucumber/runtime/TooManyInstancesException.java new file mode 100644 index 0000000000..463f01211e --- /dev/null +++ b/core/src/main/java/cucumber/runtime/TooManyInstancesException.java @@ -0,0 +1,14 @@ +package cucumber.runtime; + +import java.util.Collection; + +public class TooManyInstancesException extends CucumberException { + + public TooManyInstancesException(Collection instances) { + super(createMessage(instances)); + } + + private static String createMessage(Collection instances) { + return String.format("Expected only one instance, but found too many: " + instances); + } +} diff --git a/java/src/main/java/cucumber/runtime/java/JavaBackend.java b/java/src/main/java/cucumber/runtime/java/JavaBackend.java index 49fc2a92bb..2cc078e3e0 100644 --- a/java/src/main/java/cucumber/runtime/java/JavaBackend.java +++ b/java/src/main/java/cucumber/runtime/java/JavaBackend.java @@ -2,14 +2,7 @@ import cucumber.api.java.After; import cucumber.api.java.Before; -import cucumber.runtime.Backend; -import cucumber.runtime.ClassFinder; -import cucumber.runtime.CucumberException; -import cucumber.runtime.DuplicateStepDefinitionException; -import cucumber.runtime.Glue; -import cucumber.runtime.Reflections; -import cucumber.runtime.UnreportedStepExecutor; -import cucumber.runtime.Utils; +import cucumber.runtime.*; import cucumber.runtime.io.MultiLoader; import cucumber.runtime.io.ResourceLoader; import cucumber.runtime.io.ResourceLoaderClassFinder; @@ -61,7 +54,10 @@ public static ObjectFactory loadObjectFactory(ClassFinder classFinder) { try { Reflections reflections = new Reflections(classFinder); objectFactory = reflections.instantiateExactlyOneSubclass(ObjectFactory.class, "cucumber.runtime", new Class[0], new Object[0]); - } catch (CucumberException ce) { + } catch (TooManyInstancesException e) { + System.out.println(getMultipleObjectFactoryLogMessage()); + objectFactory = new DefaultJavaObjectFactory(); + } catch (NoInstancesException e) { objectFactory = new DefaultJavaObjectFactory(); } return objectFactory; @@ -141,4 +137,14 @@ void addHook(Annotation annotation, Method method) { glue.addAfterHook(new JavaHookDefinition(method, tagExpressions, ((After) annotation).order(), timeout, objectFactory)); } } + + private static String getMultipleObjectFactoryLogMessage() { + StringBuilder sb = new StringBuilder(); + sb.append("More than one Cucumber ObjectFactory was found in the classpath\n\n"); + sb.append("You probably may have included, for instance, cucumber-spring AND cucumber-guice as part of\n"); + sb.append("your dependencies. When this happens, Cucumber falls back to instantiating the\n"); + sb.append("DefaultJavaObjectFactory implementation which doesn't provide IoC.\n"); + sb.append("In order to enjoy IoC features, please remove the unnecessary dependencies from your classpath.\n"); + return sb.toString(); + } }