Allow turning off stack trace collection in Guice.
By setting guice_include_stack_traces flag OFF, Guice does not collect stack traces for identifying the declaring source of a binding. Instead it uses the first non-skipped module class name from the modules stack. As a result, in some cases, error messages can be slightly different with this flag. For example, the file name and line number are not always available.
A sample error message with this flag :
Guice creation errors:
1) Received null converting foo (bound at com.google.inject.TypeConversionTest.configure(Unknown Source) (via modules: com.google.inject.TypeConversionTest -> com.google.inject.TypeConversionTest)) to java.util.Date
using CustomConverter which matches only(java.util.Date) (bound at com.google.inject.TypeConversionTest.configure(Unknown Source) (via modules: com.google.inject.TypeConversionTest -> com.google.inject.TypeConversionTest -> com.google.inject.TypeConversionTest)).
while locating java.util.Date annotated with @com.google.inject.TypeConversionTest()
for field at com.google.inject.TypeConversionTest.date(TypeConversionTest.java:478)
at com.google.inject.TypeConversionTest.configure(Unknown Source) (via modules: com.google.inject.TypeConversionTest -> com.google.inject.TypeConversionTest)
This also changes the DEFAULT flag name to ONLY_FOR_DECLARTION_SOURCE.
Adds InternalFlags.getIncludeStackTraceOption() to wrap system property access.
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=53610378
diff --git a/build.xml b/build.xml
index 544117b..81ed3ee 100644
--- a/build.xml
+++ b/build.xml
@@ -78,11 +78,24 @@
excludes="build/**,**/.svn/**,classes/**,.settings/**,bin/**,latest-api-diffs/**,latest-javadoc/**,.classpath,.project"/>
</zip>
</target>
-
+
<target name="test.dist"
- depends="jar, test.compile-with-deps"
- description="Execute JUnit tests against distribution jar.">
- <java fork="true"
+ description="Execute JUnit tests against distribution jar.">
+ <antcall target="test.dist.run">
+ <param name="jvmarg-value" value="-Dguice_include_stack_traces="/>
+ </antcall>
+ <antcall target="test.dist.run">
+ <param name="jvmarg-value" value="-Dguice_include_stack_traces=OFF"/>
+ </antcall>
+ <antcall target="test.dist.run">
+ <param name="jvmarg-value" value="-Dguice_include_stack_traces=COMPLETE"/>
+ </antcall>
+ </target>
+
+ <target name="test.dist.run"
+ depends="jar, test.compile-with-deps"
+ description="Execute JUnit tests against distribution jar with the given jvmarg.">
+ <java fork="true"
classname="junit.textui.TestRunner"
failonerror="true"
taskname="junit">
@@ -98,7 +111,8 @@
<pathelement location="lib/build/bnd-0.0.384.jar"/>
<pathelement location="lib/build/felix-2.0.5.jar"/>
</classpath>
- <arg value="com.google.inject.AllTests"/>
+ <arg value="com.google.inject.AllTests"/>
+ <jvmarg value="${jvmarg-value}"/>
<syspropertyset>
<propertyref name="guice.custom.loader"/>
<propertyref name="version"/>
diff --git a/core/src/com/google/inject/internal/InternalFlags.java b/core/src/com/google/inject/internal/InternalFlags.java
new file mode 100644
index 0000000..9458281
--- /dev/null
+++ b/core/src/com/google/inject/internal/InternalFlags.java
@@ -0,0 +1,33 @@
+package com.google.inject.internal;
+
+
+/**
+ * Contains flags for Guice.
+ */
+public class InternalFlags {
+
+ /**
+ * The options for Guice stack trace collection.
+ */
+ public enum IncludeStackTraceOption {
+ // No stack trace collection
+ OFF,
+ // Minimum stack trace collection (Default)
+ ONLY_FOR_DECLARING_SOURCE,
+ // Full stack trace for everything
+ COMPLETE
+ }
+
+
+ public static IncludeStackTraceOption getIncludeStackTraceOption() {
+ String propertyValue = System.getProperty(
+ "guice_include_stack_traces");
+ if (IncludeStackTraceOption.OFF.name().equals(propertyValue)) {
+ return IncludeStackTraceOption.OFF;
+ }
+ if (IncludeStackTraceOption.COMPLETE.name().equals(propertyValue)) {
+ return IncludeStackTraceOption.COMPLETE;
+ }
+ return IncludeStackTraceOption.ONLY_FOR_DECLARING_SOURCE;
+ }
+}
diff --git a/core/src/com/google/inject/internal/util/SourceProvider.java b/core/src/com/google/inject/internal/util/SourceProvider.java
index d627554..b36cea8 100644
--- a/core/src/com/google/inject/internal/util/SourceProvider.java
+++ b/core/src/com/google/inject/internal/util/SourceProvider.java
@@ -92,4 +92,17 @@
}
throw new AssertionError();
}
+
+ /**
+ * Returns the non-skipped module class name.
+ */
+ public Object getFromClassNames(List<String> moduleClassNames) {
+ Preconditions.checkNotNull(moduleClassNames, "The list of module class names cannot be null.");
+ for (final String moduleClassName : moduleClassNames) {
+ if (!shouldBeSkipped(moduleClassName)) {
+ return new StackTraceElement(moduleClassName, "configure", null, -1);
+ }
+ }
+ return UNKNOWN_SOURCE;
+ }
}
diff --git a/core/src/com/google/inject/internal/util/StackTraceElements.java b/core/src/com/google/inject/internal/util/StackTraceElements.java
index db10c28..69f930f 100644
--- a/core/src/com/google/inject/internal/util/StackTraceElements.java
+++ b/core/src/com/google/inject/internal/util/StackTraceElements.java
@@ -33,6 +33,10 @@
*/
public class StackTraceElements {
+ private static final StackTraceElement[] EMPTY_STACK_TRACE = new StackTraceElement[0];
+ private static final InMemoryStackTraceElement[] EMPTY_INMEMORY_STACK_TRACE =
+ new InMemoryStackTraceElement[0];
+
/*if[AOP]*/
static final LoadingCache<Class<?>, LineNumbers> lineNumbersCache =
CacheBuilder.newBuilder().weakKeys().softValues().build(
@@ -100,6 +104,9 @@
*/
public static InMemoryStackTraceElement[] convertToInMemoryStackTraceElement(
StackTraceElement[] stackTraceElements) {
+ if (stackTraceElements.length == 0) {
+ return EMPTY_INMEMORY_STACK_TRACE;
+ }
InMemoryStackTraceElement[] inMemoryStackTraceElements =
new InMemoryStackTraceElement[stackTraceElements.length];
for (int i = 0; i < stackTraceElements.length; i++) {
@@ -114,6 +121,9 @@
*/
public static StackTraceElement[] convertToStackTraceElement(
InMemoryStackTraceElement[] inMemoryStackTraceElements) {
+ if (inMemoryStackTraceElements.length == 0) {
+ return EMPTY_STACK_TRACE;
+ }
StackTraceElement[] stackTraceElements =
new StackTraceElement[inMemoryStackTraceElements.length];
for (int i = 0; i < inMemoryStackTraceElements.length; i++) {
diff --git a/core/src/com/google/inject/spi/ElementSource.java b/core/src/com/google/inject/spi/ElementSource.java
index cfe7bb9..35246d4 100644
--- a/core/src/com/google/inject/spi/ElementSource.java
+++ b/core/src/com/google/inject/spi/ElementSource.java
@@ -19,9 +19,9 @@
* lists {@link StackTraceElement StackTraceElements} in reverse chronological order. The first
* element (index zero) is the last method call and the last element is the first method invocation.
* By default, the stack trace is not collected. The default behavior can be changed by setting the
- * {@code guice_include_stack_traces} flag value. The value can be either {@code DEFAULT} or
- * {@code COMPLETE}. Note that collecting stack traces for every binding can cause a performance hit
- * when the injector is created.
+ * {@code guice_include_stack_traces} flag value. The value can be either {@code OFF}, {@code
+ * ONLY_FOR_DECLARING_SOURCE} or {@code COMPLETE}. Note that collecting stack traces for every
+ * binding can cause a performance hit when the injector is created.
* <p>
* The sequence of class names of {@link Module modules} involved in the element creation can be
* retrieved by {@link #getModuleClassNames()}. Similar to {@link #getStackTrace()}, the order is
@@ -35,7 +35,7 @@
public final class ElementSource {
/**
- * The {@link ElementSource source} of element that this element created from (if there is any),
+ * The {@link ElementSource source} of element that this element created from (if there is any),
* otherwise {@code null}.
*/
final ElementSource originalElementSource;
@@ -44,8 +44,8 @@
final ModuleSource moduleSource;
/**
- * The partial call stack that starts at the last module {@link Module#Configure(Binder)
- * configure(Binder)} call.
+ * The partial call stack that starts at the last module {@link Module#Configure(Binder)
+ * configure(Binder)} call. The value is empty if stack trace collection is off.
*/
final InMemoryStackTraceElement[] partialCallStack;
@@ -59,7 +59,7 @@
/**
* Creates a new {@ElementSource} from the given parameters.
- * @param originalElementSource The source of element that this element created from (if there is
+ * @param originalElementSource The source of element that this element created from (if there is
* any), otherwise {@code null}.
* @param declaringSource the source (in)directly declared the element.
* @param moduleSource the moduleSource when the element is bound
@@ -68,17 +68,17 @@
*/
ElementSource(/* @Nullable */ ElementSource originalSource, Object declaringSource,
ModuleSource moduleSource, StackTraceElement[] partialCallStack) {
+ Preconditions.checkNotNull(declaringSource, "declaringSource cannot be null.");
Preconditions.checkNotNull(moduleSource, "moduleSource cannot be null.");
Preconditions.checkNotNull(partialCallStack, "partialCallStack cannot be null.");
- Preconditions.checkNotNull(declaringSource, "declaringSource cannot be null.");
this.originalElementSource = originalSource;
+ this.declaringSource = declaringSource;
this.moduleSource = moduleSource;
this.partialCallStack = StackTraceElements.convertToInMemoryStackTraceElement(partialCallStack);
- this.declaringSource = declaringSource;
}
/**
- * Returns the {@link ElementSource} of the element this was created or copied from. If this was
+ * Returns the {@link ElementSource} of the element this was created or copied from. If this was
* not created or copied from another element, returns {@code null}.
*/
public ElementSource getOriginalElementSource() {
@@ -96,29 +96,17 @@
}
/**
- * Returns the class names of modules involved in creating this {@link Element}. The first
+ * Returns the class names of modules involved in creating this {@link Element}. The first
* element (index 0) is the class name of module that defined the element, and the last element
- * is the class name of root module. In the cases where the class name is null an empty string
- * is returned.
+ * is the class name of root module.
*/
public List<String> getModuleClassNames() {
- String[] classNames = new String[moduleSource.size()];
- ModuleSource current = moduleSource;
- int cursor = 0;
- while (current != null) {
- classNames[cursor] = current.getModuleClassName();
- if (classNames[cursor] == null) {
- classNames[cursor] = "";
- }
- current = current.getParent();
- cursor++;
- }
- return ImmutableList.<String>copyOf(classNames);
+ return moduleSource.getModuleClassNames();
}
-
+
/**
- * Returns the position of {@link Module#configure(Binder) configure(Binder)} method call in the
- * {@link #getStackTrace() stack trace} for modules that their classes returned by
+ * Returns the position of {@link Module#configure(Binder) configure(Binder)} method call in the
+ * {@link #getStackTrace() stack trace} for modules that their classes returned by
* {@link #getModuleClassNames()}. For example, if the stack trace looks like the following:
* <p>
* {@code
@@ -131,28 +119,23 @@
* <p>
* 1 and 3 are returned.
* <p>
- * In the cases where stack trace is not available (i.e.,the stack trace was not collected),
- * it returns an empty array.
+ * In the cases where stack trace is not available (i.e., the stack trace was not collected),
+ * it returns -1 for all module positions.
*/
public List<Integer> getModuleConfigurePositionsInStackTrace() {
- if (!isStackTraceRetained()) {
- return ImmutableList.<Integer>of();
- }
int size = moduleSource.size();
Integer[] positions = new Integer[size];
- int position = partialCallStack.length;
- positions[0] = position - 1;
+ int chunkSize = partialCallStack.length;
+ positions[0] = chunkSize - 1;
ModuleSource current = moduleSource;
- int cursor = 1;
- while (cursor < size) {
- position += current.getPartialCallStack().length;
- positions[cursor] = position - 1;
+ for (int cursor = 1; cursor < size; cursor++) {
+ chunkSize = current.getPartialCallStackSize();
+ positions[cursor] = positions[cursor - 1] + chunkSize;
current = current.getParent();
- cursor++;
}
return ImmutableList.<Integer>copyOf(positions);
}
-
+
/**
* Returns the sequence of method calls that ends at one of {@link Binder} {@code bindXXX()}
* methods and eventually defines the element. Note that {@link #getStackTrace()} lists {@link
@@ -164,7 +147,7 @@
public StackTraceElement[] getStackTrace() {
int modulesCallStackSize = moduleSource.getStackTraceSize();
int chunkSize = partialCallStack.length;
- int size = moduleSource.getStackTraceSize() + partialCallStack.length;
+ int size = moduleSource.getStackTraceSize() + chunkSize;
StackTraceElement[] callStack = new StackTraceElement[size];
System.arraycopy(
StackTraceElements.convertToStackTraceElement(partialCallStack), 0, callStack, 0,
@@ -172,13 +155,6 @@
System.arraycopy(moduleSource.getStackTrace(), 0, callStack, chunkSize, modulesCallStackSize);
return callStack;
}
-
- /**
- * Returns true if stack trace was collected.
- */
- public boolean isStackTraceRetained() {
- return (partialCallStack.length > 0);
- }
/**
* Returns {@code getDeclaringSource().toString()} value.
diff --git a/core/src/com/google/inject/spi/Elements.java b/core/src/com/google/inject/spi/Elements.java
index cfbda5b..44d49ff 100644
--- a/core/src/com/google/inject/spi/Elements.java
+++ b/core/src/com/google/inject/spi/Elements.java
@@ -17,10 +17,13 @@
package com.google.inject.spi;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.inject.internal.InternalFlags.IncludeStackTraceOption;
+import static com.google.inject.internal.InternalFlags.getIncludeStackTraceOption;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
+
import com.google.inject.AbstractModule;
import com.google.inject.Binder;
import com.google.inject.Binding;
@@ -65,14 +68,6 @@
*/
public final class Elements {
- private enum IncludeStackTraceFlagValues {
- // Minimum stack trace collection
- DEFAULT,
- // Full stack trace for everything
- COMPLETE
- }
-
-
private static final BindingTargetVisitor<Object, Object> GET_INSTANCE_VISITOR
= new DefaultBindingTargetVisitor<Object, Object>() {
@Override public Object visit(InstanceBinding<?> binding) {
@@ -113,14 +108,12 @@
for (Module module : modules) {
binder.install(module);
}
- if (collectCompleteStackTrace()) {
- // Free the memory consumed by the stack trace elements cache
- StackTraceElements.clearCache();
- }
+ // Free the memory consumed by the stack trace elements cache
+ StackTraceElements.clearCache();
binder.rehashKeys();
return Collections.unmodifiableList(binder.elements);
}
-
+
private static class ElementsAsModule implements Module {
private final Iterable<? extends Element> elements;
@@ -147,11 +140,6 @@
return (BindingTargetVisitor<T, T>) GET_INSTANCE_VISITOR;
}
- private static boolean collectCompleteStackTrace() {
- return IncludeStackTraceFlagValues.COMPLETE.name().equals(
- System.getProperty("guice_include_stack_traces"));
- }
-
private static class RecordingBinder implements Binder, PrivateBinder, RehashableKeys {
private final Stage stage;
private final Set<Module> modules;
@@ -245,7 +233,7 @@
public void bindListener(Matcher<? super TypeLiteral<?>> typeMatcher, TypeListener listener) {
elements.add(new TypeListenerBinding(getElementSource(), listener, typeMatcher));
}
-
+
public void bindListener(Matcher<? super Binding<?>> bindingMatcher,
ProvisionListener... listeners) {
elements.add(new ProvisionListenerBinding(getElementSource(), bindingMatcher, listeners));
@@ -266,7 +254,7 @@
}
if (module instanceof PrivateModule) {
binder = binder.newPrivateBinder();
- }
+ }
try {
module.configure(binder);
} catch (RuntimeException e) {
@@ -336,7 +324,7 @@
elements.add(new TypeConverterBinding(getElementSource(), typeMatcher, converter));
}
- public RecordingBinder withSource(final Object source) {
+ public RecordingBinder withSource(final Object source) {
return new RecordingBinder(this, source, null);
}
@@ -357,15 +345,15 @@
rehashables.add(binder);
return binder;
}
-
+
public void disableCircularProxies() {
elements.add(new DisableCircularProxiesOption(getElementSource()));
}
-
+
public void requireExplicitBindings() {
- elements.add(new RequireExplicitBindingsOption(getElementSource()));
+ elements.add(new RequireExplicitBindingsOption(getElementSource()));
}
-
+
public void requireAtInjectOnConstructors() {
elements.add(new RequireAtInjectOnConstructorsOption(getElementSource()));
}
@@ -403,10 +391,10 @@
private ModuleSource getModuleSource(Module module) {
StackTraceElement[] partialCallStack;
- if (!collectCompleteStackTrace()) {
- partialCallStack = new StackTraceElement[0];
- } else {
+ if (getIncludeStackTraceOption() == IncludeStackTraceOption.COMPLETE) {
partialCallStack = getPartialCallStack(new Throwable().getStackTrace());
+ } else {
+ partialCallStack = new StackTraceElement[0];
}
if (moduleSource == null) {
return new ModuleSource(module, partialCallStack);
@@ -415,39 +403,47 @@
}
private ElementSource getElementSource() {
- Object declaringSource = source;
// Full call stack
- StackTraceElement[] callStack;
+ StackTraceElement[] callStack = null;
// The call stack starts from current top module configure and ends at this method caller
- StackTraceElement[] partialCallStack;
- if (!collectCompleteStackTrace()) {
- callStack = null;
- partialCallStack = new StackTraceElement[0];
- } else {
- callStack = new Throwable().getStackTrace();
- partialCallStack = getPartialCallStack(callStack);
- }
- if (declaringSource == null) {
- // TODO(salmanmir): can we avoid getting the full stack trace by using modules stack?
- if (callStack == null) {
- callStack = new Throwable().getStackTrace();
- }
- declaringSource = sourceProvider.get(callStack);
- }
+ StackTraceElement[] partialCallStack = new StackTraceElement[0];
+ // The element original source
ElementSource originalSource = null;
+ // The element declaring source
+ Object declaringSource = source;
if (declaringSource instanceof ElementSource) {
originalSource = (ElementSource) declaringSource;
declaringSource = originalSource.getDeclaringSource();
}
+ IncludeStackTraceOption stackTraceOption = getIncludeStackTraceOption();
+ if (stackTraceOption == IncludeStackTraceOption.COMPLETE ||
+ (stackTraceOption == IncludeStackTraceOption.ONLY_FOR_DECLARING_SOURCE
+ && declaringSource == null)) {
+ callStack = new Throwable().getStackTrace();
+ }
+ if (stackTraceOption == IncludeStackTraceOption.COMPLETE) {
+ partialCallStack = getPartialCallStack(callStack);
+ }
+ if (declaringSource == null) {
+ // So 'source' and 'originalSource' are null otherwise declaringSource has some value
+ if (stackTraceOption == IncludeStackTraceOption.COMPLETE ||
+ stackTraceOption == IncludeStackTraceOption.ONLY_FOR_DECLARING_SOURCE) {
+ // With the above conditions and assignments 'callStack' is non-null
+ declaringSource = sourceProvider.get(callStack);
+ } else { // or if (stackTraceOption == IncludeStackTraceOptions.OFF)
+ // As neither 'declaring source' nor 'call stack' is available use 'module source'
+ declaringSource = sourceProvider.getFromClassNames(moduleSource.getModuleClassNames());
+ }
+ }
// Build the binding call stack
return new ElementSource(
originalSource, declaringSource, moduleSource, partialCallStack);
}
/**
- * Removes the {@link #moduleSource} call stack from the beginning of current call stack. It
- * also removes the last two elements in order to make {@link #install(Module)} the last call
- * in the call stack.
+ * Removes the {@link #moduleSource} call stack from the beginning of current call stack. It
+ * also removes the last two elements in order to make {@link #install(Module)} the last call
+ * in the call stack.
*/
private StackTraceElement[] getPartialCallStack(StackTraceElement[] callStack) {
int toSkip = 0;
@@ -461,7 +457,7 @@
System.arraycopy(callStack, 1, partialCallStack, 0, chunkSize);
return partialCallStack;
}
-
+
@Override public void rehashKeys() {
for (RehashableKeys rehashable : rehashables) {
rehashable.rehashKeys();
diff --git a/core/src/com/google/inject/spi/ModuleSource.java b/core/src/com/google/inject/spi/ModuleSource.java
index 627ff4d..4e2a549 100644
--- a/core/src/com/google/inject/spi/ModuleSource.java
+++ b/core/src/com/google/inject/spi/ModuleSource.java
@@ -1,20 +1,22 @@
package com.google.inject.spi;
import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
import com.google.inject.Module;
import com.google.inject.internal.util.StackTraceElements;
import com.google.inject.internal.util.StackTraceElements.InMemoryStackTraceElement;
+import java.util.List;
+
/**
* Associated to a {@link Module module}, provides the module class name, the parent module {@link
* ModuleSource source}, and the call stack that ends just before the module {@link
* Module#configure(Binder) configure(Binder)} method invocation.
*/
final class ModuleSource {
-
+
/**
- * The class name of module that this {@link ModuleSource} associated to. This value is null when
- * the module class {@link Class#getName() getName()} returns null.
+ * The class name of module that this {@link ModuleSource} associated to.
*/
private final String moduleClassName;
@@ -27,9 +29,9 @@
* The chunk of call stack that starts from the parent module {@link Module#configure(Binder)
* configure(Binder)} call and ends just before the module {@link Module#configure(Binder)
* configure(Binder)} method invocation. For a module without a parent module the chunk starts
- * from the bottom of call stack.
+ * from the bottom of call stack. The array is non-empty if stack trace collection is on.
*/
- private final InMemoryStackTraceElement[] partialCallStack;
+ private final InMemoryStackTraceElement[] partialCallStack;
/**
* Creates a new {@link ModuleSource} with a {@literal null} parent.
@@ -60,7 +62,7 @@
}
/**
- * Returns the corresponding module class name. The value can be null.
+ * Returns the corresponding module class name.
*
* @see Class#getName()
*/
@@ -69,16 +71,17 @@
}
/**
- * Returns the chunk of call stack that starts from the parent module {@link
- * Module#configure(Binder) configure(Binder)} call and ends just before the module {@link
- * Module#configure(Binder) configure(Binder)} method invocation
+ * Returns the chunk of call stack that starts from the parent module {@link
+ * Module#configure(Binder) configure(Binder)} call and ends just before the module {@link
+ * Module#configure(Binder) configure(Binder)} method invocation. The return array is non-empty
+ * only if stack trace collection is on.
*/
StackTraceElement[] getPartialCallStack() {
return StackTraceElements.convertToStackTraceElement(partialCallStack);
}
/**
- * Returns the size of partial call stack.
+ * Returns the size of partial call stack if stack trace collection is on otherwise zero.
*/
int getPartialCallStackSize() {
return partialCallStack.length;
@@ -101,7 +104,23 @@
ModuleSource getParent() {
return parent;
}
-
+
+ /**
+ * Returns the class names of modules in this module source. The first element (index 0) is filled
+ * by this object {@link #getModuleClassName()}. The second element is filled by the parent's
+ * {@link #getModuleClassName()} and so on.
+ */
+ List<String> getModuleClassNames() {
+ ImmutableList.Builder<String> classNames = ImmutableList.builder();
+ ModuleSource current = this;
+ while (current != null) {
+ String className = current.moduleClassName;
+ classNames.add(className);
+ current = current.parent;
+ }
+ return classNames.build();
+ }
+
/**
* Returns the size of {@link ModuleSource ModuleSources} chain (all parents) that ends at this
* object.
@@ -115,22 +134,24 @@
/**
* Returns the size of call stack that ends just before the module {@link Module#configure(Binder)
- * configure(Binder)} method invocation (see {@link #getStackTrace()}).
+ * configure(Binder)} method invocation (see {@link #getStackTrace()}).
*/
int getStackTraceSize() {
if (parent == null) {
return partialCallStack.length;
}
- return parent.getStackTraceSize() + partialCallStack.length;
- }
-
+ return parent.getStackTraceSize() + partialCallStack.length;
+ }
+
/**
- * Returns the full call stack that ends just before the module {@link Module#configure(Binder)
- * configure(Binder)} method invocation.
+ * Returns the full call stack that ends just before the module {@link Module#configure(Binder)
+ * configure(Binder)} method invocation. The return array is non-empty if stack trace collection
+ * on.
*/
StackTraceElement[] getStackTrace() {
- StackTraceElement[] callStack = new StackTraceElement[getStackTraceSize()];
- int cursor = 0; // Index 0 stores the top Module.configure()
+ int stackTraceSize = getStackTraceSize();
+ StackTraceElement[] callStack = new StackTraceElement[stackTraceSize];
+ int cursor = 0;
ModuleSource current = this;
while (current != null) {
StackTraceElement[] chunk =
diff --git a/core/test/com/google/inject/Asserts.java b/core/test/com/google/inject/Asserts.java
index cd56c3a..d46a1ff 100644
--- a/core/test/com/google/inject/Asserts.java
+++ b/core/test/com/google/inject/Asserts.java
@@ -17,6 +17,8 @@
package com.google.inject;
+import static com.google.inject.internal.InternalFlags.IncludeStackTraceOption;
+import static com.google.inject.internal.InternalFlags.getIncludeStackTraceOption;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
@@ -56,6 +58,33 @@
}
/**
+ * Returns the source file appears in error messages based on {@link
+ * #getIncludeStackTraceOption()} value.
+ */
+ public static String getDeclaringSourcePart(Class clazz) {
+ if (getIncludeStackTraceOption() == IncludeStackTraceOption.OFF) {
+ return ".configure(Unknown Source";
+ }
+ return ".configure(" + clazz.getSimpleName() + ".java:";
+ }
+
+ /**
+ * Returns true if {@link #getIncludeStackTraceOption()} returns {@link
+ * IncludeStackTraceOption#OFF}.
+ */
+ public static boolean isIncludeStackTraceOff() {
+ return getIncludeStackTraceOption() == IncludeStackTraceOption.OFF;
+ }
+
+ /**
+ * Returns true if {@link #getIncludeStackTraceOption()} returns {@link
+ * IncludeStackTraceOption#COMPLETE}.
+ */
+ public static boolean isIncludeStackTraceComplete() {
+ return getIncludeStackTraceOption() == IncludeStackTraceOption.COMPLETE;
+ }
+
+ /**
* Fails unless {@code expected.equals(actual)}, {@code
* actual.equals(expected)} and their hash codes are equal. This is useful
* for testing the equals method itself.
diff --git a/core/test/com/google/inject/BinderTest.java b/core/test/com/google/inject/BinderTest.java
index 5b9f55d..5875e37 100644
--- a/core/test/com/google/inject/BinderTest.java
+++ b/core/test/com/google/inject/BinderTest.java
@@ -19,6 +19,8 @@
import static com.google.inject.Asserts.asModuleChain;
import static com.google.inject.Asserts.assertContains;
import static com.google.inject.Asserts.assertNotSerializable;
+import static com.google.inject.Asserts.getDeclaringSourcePart;
+import static com.google.inject.Asserts.isIncludeStackTraceOff;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
@@ -99,16 +101,27 @@
});
} catch (CreationException e) {
assertEquals(4, e.getErrorMessages().size());
- assertContains(e.getMessage(),
- "1) No implementation for java.lang.Runnable was bound.",
- "at " + getClass().getName(),
- "2) No implementation for " + Comparator.class.getName() + " was bound.",
- "at " + getClass().getName(),
- "3) No implementation for java.util.concurrent.Callable<java.lang.String> was bound.",
- "at " + getClass().getName(),
- "4) No implementation for java.util.Date annotated with @"
- + Named.class.getName() + "(value=date) was bound.",
- "at " + getClass().getName());
+ String segment1 = "No implementation for " + Comparator.class.getName() + " was bound.";
+ String segment2 = "No implementation for java.util.Date annotated with @"
+ + Named.class.getName() + "(value=date) was bound.";
+ String segment3 = "No implementation for java.lang.Runnable was bound.";
+ String segment4 = " No implementation for java.util.concurrent.Callable<java.lang.String> was"
+ + " bound.";
+ String atSegment = "at " + getClass().getName();
+ String sourceFileName = getDeclaringSourcePart(getClass());
+ if (isIncludeStackTraceOff()) {
+ assertContains(e.getMessage(),
+ segment1, atSegment, sourceFileName,
+ segment2, atSegment, sourceFileName,
+ segment3, atSegment, sourceFileName,
+ segment4, atSegment, sourceFileName);
+ } else {
+ assertContains(e.getMessage(),
+ segment3, atSegment, sourceFileName,
+ segment1, atSegment, sourceFileName,
+ segment4, atSegment, sourceFileName,
+ segment2, atSegment, sourceFileName);
+ }
}
}
@@ -125,7 +138,7 @@
assertContains(e.getMessage(),
"No implementation for java.lang.Runnable was bound.",
"for field at " + NeedsRunnable.class.getName(), ".runnable(BinderTest.java:",
- "at " + getClass().getName(), ".configure(BinderTest.java:");
+ "at " + getClass().getName(), getDeclaringSourcePart(getClass()));
}
}
@@ -159,7 +172,7 @@
} catch (CreationException expected) {
assertContains(expected.getMessage(),
"1) Binding points to itself.",
- "at " + getClass().getName(), ".configure(BinderTest.java:");
+ "at " + getClass().getName(), getDeclaringSourcePart(getClass()));
}
}
@@ -263,7 +276,7 @@
} catch (CreationException expected) {
assertContains(expected.getMessage(),
"1) A binding to java.lang.String[] was already configured at " + getClass().getName(),
- "at " + getClass().getName(), ".configure(BinderTest.java:");
+ "at " + getClass().getName(), getDeclaringSourcePart(getClass()));
assertContains(expected.getMessage(), "1 error");
}
@@ -317,7 +330,7 @@
assertContains(expected.getMessage(),
"1) A binding to java.lang.String was already configured at " + ConstantModule.class.getName(),
asModuleChain(ParentModule.class, FooModule.class, ConstantModule.class),
- "at " + ConstantModule.class.getName(), ".configure(BinderTest.java:",
+ "at " + ConstantModule.class.getName(), getDeclaringSourcePart(getClass()),
asModuleChain(ParentModule.class, BarModule.class, ConstantModule.class));
assertContains(expected.getMessage(), "1 error");
}
@@ -341,7 +354,7 @@
assertContains(expected.getMessage(),
"1) A binding to " + HasImplementedBy1.class.getName()
+ " was already configured at " + getClass().getName(),
- "at " + getClass().getName(), ".configure(BinderTest.java:");
+ "at " + getClass().getName(), getDeclaringSourcePart(getClass()));
assertContains(expected.getMessage(), "1 error");
}
}
@@ -459,10 +472,10 @@
} catch (CreationException expected) {
assertContains(expected.getMessage(),
"1) Binding to Provider is not allowed.",
- "at " + BinderTest.class.getName(), "configure(BinderTest.java:");
+ "at " + BinderTest.class.getName(), getDeclaringSourcePart(getClass()));
}
}
-
+
static class OuterCoreModule extends AbstractModule {
@Override protected void configure() {
install(new InnerCoreModule());
@@ -493,47 +506,47 @@
} catch (CreationException expected) {
assertContains(expected.getMessage(),
"Binding to core guice framework type is not allowed: AbstractModule.",
- "at " + InnerCoreModule.class.getName() + ".configure(BinderTest.java:",
+ "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
"Binding to core guice framework type is not allowed: Binder.",
- "at " + InnerCoreModule.class.getName() + ".configure(BinderTest.java:",
+ "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
"Binding to core guice framework type is not allowed: Binding.",
- "at " + InnerCoreModule.class.getName() + ".configure(BinderTest.java:",
+ "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
"Binding to core guice framework type is not allowed: Injector.",
- "at " + InnerCoreModule.class.getName() + ".configure(BinderTest.java:",
+ "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
"Binding to core guice framework type is not allowed: Key.",
- "at " + InnerCoreModule.class.getName() + ".configure(BinderTest.java:",
+ "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
"Binding to core guice framework type is not allowed: Module.",
- "at " + InnerCoreModule.class.getName() + ".configure(BinderTest.java:",
+ "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
"Binding to Provider is not allowed.",
- "at " + InnerCoreModule.class.getName() + ".configure(BinderTest.java:",
+ "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
"Binding to core guice framework type is not allowed: Scope.",
- "at " + InnerCoreModule.class.getName() + ".configure(BinderTest.java:",
+ "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
"Binding to core guice framework type is not allowed: Stage.",
- "at " + InnerCoreModule.class.getName() + ".configure(BinderTest.java:",
+ "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
"Binding to core guice framework type is not allowed: TypeLiteral.",
- "at " + InnerCoreModule.class.getName() + ".configure(BinderTest.java:",
+ "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
asModuleChain(OuterCoreModule.class, InnerCoreModule.class),
"Binding to core guice framework type is not allowed: Key.",
- "at " + InnerCoreModule.class.getName() + ".configure(BinderTest.java:",
+ "at " + InnerCoreModule.class.getName() + getDeclaringSourcePart(getClass()),
asModuleChain(OuterCoreModule.class, InnerCoreModule.class));
}
}
diff --git a/core/test/com/google/inject/BindingAnnotationTest.java b/core/test/com/google/inject/BindingAnnotationTest.java
index 9827d3e..b119953 100644
--- a/core/test/com/google/inject/BindingAnnotationTest.java
+++ b/core/test/com/google/inject/BindingAnnotationTest.java
@@ -17,6 +17,7 @@
package com.google.inject;
import static com.google.inject.Asserts.assertContains;
+import static com.google.inject.Asserts.getDeclaringSourcePart;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import junit.framework.TestCase;
@@ -57,7 +58,8 @@
} catch (CreationException expected) {
assertContains(expected.getMessage(), "No implementation for java.lang.String annotated with",
"BindingAnnotationTest$Blue(value=5) was bound",
- "at " + BindingAnnotationTest.class.getName(), ".configure(BindingAnnotationTest.java:");
+ "at " + BindingAnnotationTest.class.getName(),
+ getDeclaringSourcePart(getClass()));
}
}
@@ -86,7 +88,8 @@
} catch (CreationException expected) {
assertContains(expected.getMessage(), "No implementation for java.lang.String annotated with",
"BindingAnnotationTest$Color",
- "at " + BindingAnnotationTest.class.getName(), ".configure(BindingAnnotationTest.java:");
+ "at " + BindingAnnotationTest.class.getName(),
+ getDeclaringSourcePart(getClass()));
}
}
@@ -104,7 +107,8 @@
} catch (CreationException expected) {
assertContains(expected.getMessage(), "No implementation for java.lang.String annotated with",
"BindingAnnotationTest$Blue(value=5) was bound",
- "at " + BindingAnnotationTest.class.getName(), ".configure(BindingAnnotationTest.java:");
+ "at " + BindingAnnotationTest.class.getName(),
+ getDeclaringSourcePart(getClass()));
}
}
diff --git a/core/test/com/google/inject/DuplicateBindingsTest.java b/core/test/com/google/inject/DuplicateBindingsTest.java
index eb9f503..27a2fd1 100644
--- a/core/test/com/google/inject/DuplicateBindingsTest.java
+++ b/core/test/com/google/inject/DuplicateBindingsTest.java
@@ -16,7 +16,7 @@
package com.google.inject;
-import static com.google.inject.Asserts.assertContains;
+import static com.google.inject.Asserts.*;
import static com.google.inject.name.Names.named;
import com.google.common.base.Objects;
@@ -85,7 +85,8 @@
fail("should have failed");
} catch(CreationException ce) {
assertContains(ce.getMessage(),
- "A binding to " + Foo.class.getName() + " was already configured at " + FailingProviderModule.class.getName(),
+ "A binding to " + Foo.class.getName() + " was already configured " +
+ "at " + FailingProviderModule.class.getName(),
"at " + FailingProviderModule.class.getName()
);
}
@@ -123,7 +124,7 @@
new ScopedModule(Scopes.NO_SCOPE, foo, pFoo, pclFoo, clFoo, cFoo)
);
}
-
+
public void testMixedScopeFails() {
try {
Guice.createInjector(
@@ -132,20 +133,25 @@
);
fail("expected exception");
} catch(CreationException ce) {
- assertContains(ce.getMessage(),
- "A binding to " + Foo.class.getName() + " annotated with " + named("pInstance") + " was already configured at " + SimpleModule.class.getName(),
- "at " + ScopedModule.class.getName(),
- "A binding to " + Foo.class.getName() + " annotated with " + named("pKey") + " was already configured at " + SimpleModule.class.getName(),
- "at " + ScopedModule.class.getName(),
- "A binding to " + Foo.class.getName() + " annotated with " + named("linkedKey") + " was already configured at " + SimpleModule.class.getName(),
- "at " + ScopedModule.class.getName(),
- "A binding to " + FooImpl.class.getName() + " was already configured at " + SimpleModule.class.getName(),
- "at " + ScopedModule.class.getName(),
- "A binding to " + Foo.class.getName() + " annotated with " + named("constructor") + " was already configured at " + SimpleModule.class.getName(),
- "at " + ScopedModule.class.getName());
+ String segment1 = "A binding to " + Foo.class.getName() + " annotated with "
+ + named("pInstance") + " was already configured at " + SimpleModule.class.getName();
+ String segment2 = "A binding to " + Foo.class.getName() + " annotated with " + named("pKey")
+ + " was already configured at " + SimpleModule.class.getName();
+ String segment3 = "A binding to " + Foo.class.getName() + " annotated with "
+ + named("constructor") + " was already configured at " + SimpleModule.class.getName();
+ String segment4 = "A binding to " + FooImpl.class.getName() + " was already configured at "
+ + SimpleModule.class.getName();
+ String atSegment = "at " + ScopedModule.class.getName();
+ if (isIncludeStackTraceOff()) {
+ assertContains(ce.getMessage(), segment1 , atSegment, segment2, atSegment, segment3,
+ atSegment, segment4, atSegment);
+ } else {
+ assertContains(ce.getMessage(), segment1 , atSegment, segment2, atSegment, segment4,
+ atSegment, segment3, atSegment);
+ }
}
}
-
+
@SuppressWarnings("unchecked")
public void testMixedTargetsFails() {
try {
diff --git a/core/test/com/google/inject/NullableInjectionPointTest.java b/core/test/com/google/inject/NullableInjectionPointTest.java
index 10eaefd..9cf22cc 100644
--- a/core/test/com/google/inject/NullableInjectionPointTest.java
+++ b/core/test/com/google/inject/NullableInjectionPointTest.java
@@ -1,6 +1,7 @@
package com.google.inject;
import static com.google.inject.Asserts.assertContains;
+import static com.google.inject.Asserts.getDeclaringSourcePart;
import junit.framework.TestCase;
@@ -122,7 +123,7 @@
} catch (CreationException expected) {
assertContains(expected.getMessage(),
"Binding to null instances is not allowed.",
- "at " + getClass().getName(), ".configure(NullableInjectionPointTest.java:");
+ "at " + getClass().getName(), getDeclaringSourcePart(getClass()));
}
}
diff --git a/core/test/com/google/inject/ParentInjectorTest.java b/core/test/com/google/inject/ParentInjectorTest.java
index 4ea47ed..4940b77 100644
--- a/core/test/com/google/inject/ParentInjectorTest.java
+++ b/core/test/com/google/inject/ParentInjectorTest.java
@@ -17,6 +17,7 @@
package com.google.inject;
import static com.google.inject.Asserts.assertContains;
+import static com.google.inject.Asserts.getDeclaringSourcePart;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@@ -44,8 +45,8 @@
fail("Created the same explicit binding on both parent and child");
} catch (CreationException e) {
assertContains(e.getMessage(), "A binding to ", A.class.getName(), " was already configured",
- " at ", getClass().getName(), ".configure(ParentInjectorTest.java:",
- " at ", getClass().getName(), ".configure(ParentInjectorTest.java:");
+ " at ", getClass().getName(), getDeclaringSourcePart(getClass()),
+ " at ", getClass().getName(), getDeclaringSourcePart(getClass()));
}
}
diff --git a/core/test/com/google/inject/PrivateModuleTest.java b/core/test/com/google/inject/PrivateModuleTest.java
index 7477f5a..05db62b 100644
--- a/core/test/com/google/inject/PrivateModuleTest.java
+++ b/core/test/com/google/inject/PrivateModuleTest.java
@@ -18,6 +18,7 @@
import static com.google.inject.Asserts.asModuleChain;
import static com.google.inject.Asserts.assertContains;
+import static com.google.inject.Asserts.getDeclaringSourcePart;
import static com.google.inject.name.Names.named;
import com.google.common.collect.ImmutableSet;
@@ -121,7 +122,7 @@
} catch (CreationException expected) {
assertContains(expected.getMessage(), "Cannot expose java.lang.String on a standard binder. ",
"Exposed bindings are only applicable to private binders.",
- " at " + PrivateModuleTest.class.getName(), "configure(PrivateModuleTest.java:");
+ " at " + PrivateModuleTest.class.getName(), getDeclaringSourcePart(getClass()));
}
}
@@ -195,8 +196,8 @@
} catch (CreationException expected) {
assertContains(expected.getMessage(),
"A binding to java.lang.String was already configured at ",
- getClass().getName(), ".configure(PrivateModuleTest.java:",
- " at " + getClass().getName(), ".configure(PrivateModuleTest.java:");
+ getClass().getName(), getDeclaringSourcePart(getClass()),
+ " at " + getClass().getName(), getDeclaringSourcePart(getClass()));
}
}
@@ -218,7 +219,7 @@
} catch (CreationException expected) {
assertContains(expected.getMessage(),
"Could not expose() " + AB.class.getName() + ", it must be explicitly bound",
- ".configure(PrivateModuleTest.java:");
+ getDeclaringSourcePart(getClass()));
}
}
@@ -244,7 +245,7 @@
} catch (CreationException expected) {
assertContains(expected.getMessage(),
"1) No implementation for " + C.class.getName() + " was bound.",
- "at " + getClass().getName(), ".configure(PrivateModuleTest.java:",
+ "at " + getClass().getName(), getDeclaringSourcePart(getClass()),
"2) No implementation for " + String.class.getName(), "Named(value=a) was bound.",
"for field at " + AB.class.getName() + ".a(PrivateModuleTest.java:",
"3) No implementation for " + String.class.getName(), "Named(value=b) was bound.",
@@ -450,7 +451,7 @@
assertEquals(ImmutableSet.<Key<?>>of(Key.get(String.class, named("b"))),
privateElements.getExposedKeys());
assertContains(privateElements.getExposedSource(Key.get(String.class, named("b"))).toString(),
- PrivateModuleTest.class.getName(), ".configure(PrivateModuleTest.java:");
+ PrivateModuleTest.class.getName(), getDeclaringSourcePart(getClass()));
Injector privateInjector = privateElements.getInjector();
assertEquals("private", privateInjector.getInstance(Key.get(String.class, Names.named("a"))));
}
@@ -508,7 +509,7 @@
"while locating " + PrivateFoo.class.getName());
}
}
-
+
private static class FailingModule extends AbstractModule {
@Override protected void configure() {
bind(Collection.class).to(List.class);
diff --git a/core/test/com/google/inject/ProvisionExceptionTest.java b/core/test/com/google/inject/ProvisionExceptionTest.java
index aa4bfd5..e96a0f3 100644
--- a/core/test/com/google/inject/ProvisionExceptionTest.java
+++ b/core/test/com/google/inject/ProvisionExceptionTest.java
@@ -17,6 +17,7 @@
package com.google.inject;
import static com.google.inject.Asserts.assertContains;
+import static com.google.inject.Asserts.getDeclaringSourcePart;
import static com.google.inject.Asserts.reserialize;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
@@ -94,7 +95,8 @@
assertTrue(e.getCause() instanceof UnsupportedOperationException);
assertContains(e.getMessage(),
"1) Error in custom provider, java.lang.UnsupportedOperationException",
- "at " + ProvisionExceptionTest.class.getName(), ".configure(ProvisionExceptionTest.java");
+ "at " + ProvisionExceptionTest.class.getName(),
+ getDeclaringSourcePart(getClass()));
}
}
@@ -136,7 +138,8 @@
fail();
} catch (ProvisionException e) {
assertContains(e.getMessage(), "1) User Exception",
- "at " + ProvisionExceptionTest.class.getName(), ".configure(ProvisionExceptionTest.java");
+ "at " + ProvisionExceptionTest.class.getName(),
+ getDeclaringSourcePart(getClass()));
}
}
diff --git a/core/test/com/google/inject/RequestInjectionTest.java b/core/test/com/google/inject/RequestInjectionTest.java
index 9d3072f..dfd0f77 100644
--- a/core/test/com/google/inject/RequestInjectionTest.java
+++ b/core/test/com/google/inject/RequestInjectionTest.java
@@ -17,6 +17,7 @@
package com.google.inject;
import static com.google.inject.Asserts.assertContains;
+import static com.google.inject.Asserts.getDeclaringSourcePart;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import com.google.inject.matcher.Matchers;
@@ -128,7 +129,7 @@
assertContains(expected.getMessage(),
"1) Error in custom provider, java.lang.UnsupportedOperationException",
"for field at " + NeedsRunnable.class.getName() + ".runnable(RequestInjectionTest.java:",
- "at " + getClass().getName(), ".configure(RequestInjectionTest.java:");
+ "at " + getClass().getName(), getDeclaringSourcePart(getClass()));
}
}
diff --git a/core/test/com/google/inject/ScopesTest.java b/core/test/com/google/inject/ScopesTest.java
index 9940d53..d95c797 100644
--- a/core/test/com/google/inject/ScopesTest.java
+++ b/core/test/com/google/inject/ScopesTest.java
@@ -18,6 +18,7 @@
import static com.google.inject.Asserts.asModuleChain;
import static com.google.inject.Asserts.assertContains;
+import static com.google.inject.Asserts.getDeclaringSourcePart;
import static com.google.inject.name.Names.named;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@@ -201,7 +202,7 @@
} catch (CreationException expected) {
assertContains(expected.getMessage(),
"1) No scope is bound to " + CustomScoped.class.getName(),
- "at " + getClass().getName(), ".configure(ScopesTest.java:",
+ "at " + getClass().getName(), getDeclaringSourcePart(getClass()),
"2) No scope is bound to " + CustomScoped.class.getName(),
"at " + C.class.getName() + ".class");
}
@@ -278,7 +279,7 @@
assertContains(expected.getMessage(),
"1) Please annotate " + NotRuntimeRetainedScoped.class.getName()
+ " with @Retention(RUNTIME).",
- "at " + InnerRuntimeModule.class.getName() + ".configure(ScopesTest.java:",
+ "at " + InnerRuntimeModule.class.getName() + getDeclaringSourcePart(getClass()),
asModuleChain(OuterRuntimeModule.class, InnerRuntimeModule.class));
}
}
@@ -300,7 +301,7 @@
} catch (CreationException expected) {
assertContains(expected.getMessage(),
"1) Please annotate " + Deprecated.class.getName() + " with @ScopeAnnotation.",
- "at " + InnerDeprecatedModule.class.getName() + ".configure(ScopesTest.java:",
+ "at " + InnerDeprecatedModule.class.getName() + getDeclaringSourcePart(getClass()),
asModuleChain(OuterDeprecatedModule.class, InnerDeprecatedModule.class));
}
}
@@ -329,10 +330,10 @@
} catch (CreationException expected) {
assertContains(expected.getMessage(),
"1) Scope Scopes.NO_SCOPE is already bound to " + CustomScoped.class.getName()
- + " at " + CustomNoScopeModule.class.getName() + ".configure(ScopesTest.java:",
+ + " at " + CustomNoScopeModule.class.getName() + getDeclaringSourcePart(getClass()),
asModuleChain(OuterScopeModule.class, CustomNoScopeModule.class),
"Cannot bind Scopes.SINGLETON.",
- "at " + ScopesTest.class.getName(), ".configure(ScopesTest.java:",
+ "at " + ScopesTest.class.getName(), getDeclaringSourcePart(getClass()),
asModuleChain(OuterScopeModule.class, CustomSingletonModule.class));
}
}
diff --git a/core/test/com/google/inject/TypeConversionTest.java b/core/test/com/google/inject/TypeConversionTest.java
index de1d462..e318477 100644
--- a/core/test/com/google/inject/TypeConversionTest.java
+++ b/core/test/com/google/inject/TypeConversionTest.java
@@ -18,6 +18,7 @@
import static com.google.inject.Asserts.asModuleChain;
import static com.google.inject.Asserts.assertContains;
+import static com.google.inject.Asserts.getDeclaringSourcePart;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import com.google.common.collect.Iterables;
@@ -178,7 +179,7 @@
} catch (ConfigurationException expected) {
assertContains(expected.getMessage(),
"Error converting 'invalid' (bound at " + InnerErrorModule.class.getName()
- + ".configure(" + TypeConversionTest.class.getSimpleName() + ".java:",
+ + getDeclaringSourcePart(getClass()),
asModuleChain(OuterErrorModule.class, InnerErrorModule.class),
"using TypeConverter<Integer> which matches identicalTo(class java.lang.Integer)"
+ " (bound at [unknown source]).",
@@ -269,15 +270,16 @@
assertTrue(injector.getTypeConverterBindings().contains(converterBinding));
}
- public void testInvalidCustomValue() throws CreationException {
- Module module = new AbstractModule() {
- @Override protected void configure() {
- convertToTypes(Matchers.only(TypeLiteral.get(Date.class)), failingTypeConverter());
- bindConstant().annotatedWith(NumericValue.class).to("invalid");
- bind(DateHolder.class);
- }
- };
+ static class InvalidCustomValueModule extends AbstractModule {
+ @Override protected void configure() {
+ convertToTypes(Matchers.only(TypeLiteral.get(Date.class)), failingTypeConverter());
+ bindConstant().annotatedWith(NumericValue.class).to("invalid");
+ bind(DateHolder.class);
+ }
+ }
+ public void testInvalidCustomValue() throws CreationException {
+ Module module = new InvalidCustomValueModule();
try {
Guice.createInjector(module);
fail();
@@ -286,9 +288,9 @@
assertTrue(cause instanceof UnsupportedOperationException);
assertContains(expected.getMessage(),
"1) Error converting 'invalid' (bound at ", getClass().getName(),
- ".configure(TypeConversionTest.java:", "to java.util.Date",
+ getDeclaringSourcePart(getClass()), "to java.util.Date",
"using BrokenConverter which matches only(java.util.Date) ",
- "(bound at " + getClass().getName(), ".configure(TypeConversionTest.java:",
+ "(bound at " + getClass().getName(), getDeclaringSourcePart(getClass()),
"Reason: java.lang.UnsupportedOperationException: Cannot convert",
"at " + DateHolder.class.getName() + ".date(TypeConversionTest.java:");
}
@@ -332,12 +334,12 @@
assertContains(expected.getMessage(),
"1) Received null converting 'foo' (bound at ",
getClass().getName(),
- ".configure(TypeConversionTest.java:",
+ getDeclaringSourcePart(getClass()),
asModuleChain(OuterModule.class, InnerModule.class),
"to java.util.Date",
"using CustomConverter which matches only(java.util.Date) ",
"(bound at " + getClass().getName(),
- ".configure(TypeConversionTest.java:",
+ getDeclaringSourcePart(getClass()),
asModuleChain(OuterModule.class, InnerModule.class, ConverterNullModule.class),
"at " + DateHolder.class.getName() + ".date(TypeConversionTest.java:",
asModuleChain(OuterModule.class, InnerModule.class));
@@ -358,12 +360,12 @@
assertContains(expected.getMessage(),
"1) Type mismatch converting 'foo' (bound at ",
getClass().getName(),
- ".configure(TypeConversionTest.java:",
+ getDeclaringSourcePart(getClass()),
asModuleChain(OuterModule.class, InnerModule.class),
"to java.util.Date",
"using CustomConverter which matches only(java.util.Date) ",
"(bound at " + getClass().getName(),
- ".configure(TypeConversionTest.java:",
+ getDeclaringSourcePart(getClass()),
asModuleChain(OuterModule.class, InnerModule.class, ConverterCustomModule.class),
"Converter returned -1.",
"at " + DateHolder.class.getName() + ".date(TypeConversionTest.java:",
@@ -429,18 +431,18 @@
} catch (CreationException expected) {
assertContains(expected.getMessage(),
"1) Multiple converters can convert 'foo' (bound at ", getClass().getName(),
- ".configure(TypeConversionTest.java:",
+ getDeclaringSourcePart(getClass()),
asModuleChain(OuterAmbiguousModule.class, InnerAmbiguousModule.class),
"to java.util.Date:",
"CustomConverter which matches only(java.util.Date) (bound at "
+ Ambiguous1Module.class.getName()
- + ".configure(" + TypeConversionTest.class.getSimpleName() + ".java:",
+ + getDeclaringSourcePart(getClass()),
asModuleChain(
OuterAmbiguousModule.class, InnerAmbiguousModule.class, Ambiguous1Module.class),
"and",
"CustomConverter which matches only(java.util.Date) (bound at "
+ Ambiguous2Module.class.getName()
- + ".configure(" + TypeConversionTest.class.getSimpleName() + ".java:",
+ + getDeclaringSourcePart(getClass()),
asModuleChain(
OuterAmbiguousModule.class, InnerAmbiguousModule.class, Ambiguous2Module.class),
"Please adjust your type converter configuration to avoid overlapping matches.",
@@ -460,7 +462,7 @@
};
}
- private TypeConverter failingTypeConverter() {
+ private static TypeConverter failingTypeConverter() {
return new TypeConverter() {
public Object convert(String value, TypeLiteral<?> toType) {
throw new UnsupportedOperationException("Cannot convert");
diff --git a/core/test/com/google/inject/TypeListenerTest.java b/core/test/com/google/inject/TypeListenerTest.java
index ee0b6e2..e4b5f63 100644
--- a/core/test/com/google/inject/TypeListenerTest.java
+++ b/core/test/com/google/inject/TypeListenerTest.java
@@ -18,6 +18,7 @@
import static com.google.inject.Asserts.asModuleChain;
import static com.google.inject.Asserts.assertContains;
+import static com.google.inject.Asserts.getDeclaringSourcePart;
import static com.google.inject.matcher.Matchers.any;
import static com.google.inject.matcher.Matchers.only;
import static com.google.inject.name.Names.named;
@@ -194,12 +195,12 @@
} catch (CreationException expected) {
assertContains(expected.getMessage(),
"1) Error notifying TypeListener clumsy (bound at " + getClass().getName(),
- ".configure(TypeListenerTest.java:",
+ getDeclaringSourcePart(getClass()),
asModuleChain(OuterThrowsModule.class, InnerThrowsModule.class),
"of " + B.class.getName(),
"Reason: java.lang.ClassCastException: whoops, failure #1",
"2) Error notifying TypeListener clumsy (bound at " + getClass().getName(),
- ".configure(TypeListenerTest.java:",
+ getDeclaringSourcePart(getClass()),
asModuleChain(OuterThrowsModule.class, InnerThrowsModule.class),
"of " + C.class.getName(),
"Reason: java.lang.ClassCastException: whoops, failure #2");
@@ -216,7 +217,7 @@
} catch (ConfigurationException expected) {
assertContains(expected.getMessage(),
"1) Error notifying TypeListener clumsy (bound at " + getClass().getName(),
- ".configure(TypeListenerTest.java:",
+ getDeclaringSourcePart(getClass()),
"of " + B.class.getName(),
"Reason: java.lang.ClassCastException: whoops, failure #3");
}
@@ -228,7 +229,7 @@
} catch (ConfigurationException expected) {
assertContains(expected.getMessage(),
"1) Error notifying TypeListener clumsy (bound at " + getClass().getName(),
- ".configure(TypeListenerTest.java:",
+ getDeclaringSourcePart(getClass()),
"of " + B.class.getName(),
"Reason: java.lang.ClassCastException: whoops, failure #3");
}
@@ -295,7 +296,7 @@
} catch (CreationException expected) {
assertContains(expected.getMessage(),
"1) Error notifying TypeListener clumsy (bound at ",
- TypeListenerTest.class.getName(), ".configure(TypeListenerTest.java:",
+ TypeListenerTest.class.getName(), getDeclaringSourcePart(getClass()),
"of " + A.class.getName(),
" Reason: java.lang.ClassCastException: whoops, failure #1");
}
diff --git a/core/test/com/google/inject/internal/util/LineNumbersTest.java b/core/test/com/google/inject/internal/util/LineNumbersTest.java
index 68a2b26..da2824a 100644
--- a/core/test/com/google/inject/internal/util/LineNumbersTest.java
+++ b/core/test/com/google/inject/internal/util/LineNumbersTest.java
@@ -17,6 +17,7 @@
package com.google.inject.internal.util;
import static com.google.inject.Asserts.assertContains;
+import static com.google.inject.Asserts.getDeclaringSourcePart;
import com.google.inject.AbstractModule;
import com.google.inject.CreationException;
@@ -46,7 +47,7 @@
assertContains(expected.getMessage(),
"1) No implementation for " + B.class.getName() + " was bound.",
"for parameter 0 at " + A.class.getName() + ".<init>(LineNumbersTest.java:",
- "at " + LineNumbersTest.class.getName(), ".configure(LineNumbersTest.java:");
+ "at " + LineNumbersTest.class.getName(), getDeclaringSourcePart(getClass()));
}
}
@@ -75,7 +76,7 @@
assertContains(expected.getMessage(),
"1) No implementation for " + B.class.getName() + " was bound.",
"for parameter 0 at " + A.class.getName() + ".<init>(LineNumbersTest.java:",
- "at " + LineNumbersTest.class.getName(), ".configure(LineNumbersTest.java:");
+ "at " + LineNumbersTest.class.getName(), getDeclaringSourcePart(getClass()));
}
}
@@ -125,7 +126,7 @@
assertContains(expected.getMessage(),
"1) No implementation for " + B.class.getName() + " was bound.",
"for parameter 0 at " + GeneratingClassLoader.name + ".<init>(Unknown Source)",
- "at " + LineNumbersTest.class.getName(), ".configure(LineNumbersTest.java:");
+ "at " + LineNumbersTest.class.getName(), getDeclaringSourcePart(getClass()));
}
}
diff --git a/core/test/com/google/inject/spi/ElementSourceTest.java b/core/test/com/google/inject/spi/ElementSourceTest.java
index 5c63f4a..93fbeac 100644
--- a/core/test/com/google/inject/spi/ElementSourceTest.java
+++ b/core/test/com/google/inject/spi/ElementSourceTest.java
@@ -1,5 +1,6 @@
package com.google.inject.spi;
+import static com.google.inject.internal.InternalFlags.getIncludeStackTraceOption;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import com.google.inject.AbstractModule;
@@ -21,15 +22,10 @@
*/
public class ElementSourceTest extends TestCase {
- private static final StackTraceElement BINDER_INSTALL =
- new StackTraceElement("com.google.inject.spi.Elements$RecordingBinder", "install",
+ private static final StackTraceElement BINDER_INSTALL =
+ new StackTraceElement("com.google.inject.spi.Elements$RecordingBinder", "install",
"Unknown Source", 234 /* line number*/);
-
- @Override
- protected void tearDown() throws Exception {
- System.clearProperty("guice_include_stack_traces");
- }
-
+
public void testCallStackSize() {
ModuleSource moduleSource = createModuleSource();
StackTraceElement[] bindingCallStack = new StackTraceElement[3];
@@ -42,10 +38,9 @@
ElementSource elementSource = new ElementSource(
null /* No original element source */, "" /* Don't care */, moduleSource, bindingCallStack);
assertEquals(10 /* call stack size */, elementSource.getStackTrace().length);
- }
+ }
- public void testGetCallStack_IntegrationTest_Default() throws Exception {
- System.setProperty("guice_include_stack_traces", "DEFAULT");
+ public void testGetCallStack_IntegrationTest() throws Exception {
List<Element> elements = Elements.getElements(new A());
for (Element element : elements) {
if (element instanceof Binding) {
@@ -53,105 +48,95 @@
Class<? extends Annotation> annotationType = binding.getKey().getAnnotationType();
if (annotationType != null && annotationType.equals(SampleAnnotation.class)) {
ElementSource elementSource = (ElementSource) binding.getSource();
- // Check module stack
List<String> moduleClassNames = elementSource.getModuleClassNames();
+ // Check module class names
// Module C
assertEquals("com.google.inject.spi.ElementSourceTest$C", moduleClassNames.get(0));
// Module B
assertEquals("com.google.inject.spi.ElementSourceTest$B", moduleClassNames.get(1));
// Module A
assertEquals("com.google.inject.spi.ElementSourceTest$A", moduleClassNames.get(2));
- // Check call stack
StackTraceElement[] callStack = elementSource.getStackTrace();
- assertEquals(0, elementSource.getStackTrace().length);
- return;
+ switch(getIncludeStackTraceOption()) {
+ case OFF:
+ // Check declaring source
+ StackTraceElement stackTraceElement =
+ (StackTraceElement) elementSource.getDeclaringSource();
+ assertEquals(new StackTraceElement(
+ "com.google.inject.spi.ElementSourceTest$C", "configure", null, -1),
+ stackTraceElement);
+ // Check call stack
+ assertEquals(0, callStack.length);
+ return;
+ case ONLY_FOR_DECLARING_SOURCE:
+ // Check call stack
+ assertEquals(0, callStack.length);
+ return;
+ case COMPLETE:
+ // Check call stack
+ int skippedCallStackSize = new Throwable().getStackTrace().length - 1;
+ assertEquals(skippedCallStackSize + 15, elementSource.getStackTrace().length);
+ assertEquals("com.google.inject.spi.Elements$RecordingBinder",
+ callStack[0].getClassName());
+ assertEquals("com.google.inject.spi.Elements$RecordingBinder",
+ callStack[1].getClassName());
+ assertEquals("com.google.inject.AbstractModule",
+ callStack[2].getClassName());
+ // Module C
+ assertEquals("com.google.inject.spi.ElementSourceTest$C",
+ callStack[3].getClassName());
+ assertEquals("configure",
+ callStack[3].getMethodName());
+ assertEquals("Unknown Source",
+ callStack[3].getFileName());
+ assertEquals("com.google.inject.AbstractModule",
+ callStack[4].getClassName());
+ assertEquals("com.google.inject.spi.Elements$RecordingBinder",
+ callStack[5].getClassName());
+ // Module B
+ assertEquals("com.google.inject.spi.ElementSourceTest$B",
+ callStack[6].getClassName());
+ assertEquals("com.google.inject.spi.Elements$RecordingBinder",
+ callStack[7].getClassName());
+ // Module A
+ assertEquals("com.google.inject.AbstractModule",
+ callStack[8].getClassName());
+ assertEquals("com.google.inject.spi.ElementSourceTest$A",
+ callStack[9].getClassName());
+ assertEquals("com.google.inject.AbstractModule",
+ callStack[10].getClassName());
+ assertEquals("com.google.inject.spi.Elements$RecordingBinder",
+ callStack[11].getClassName());
+ assertEquals("com.google.inject.spi.Elements",
+ callStack[12].getClassName());
+ assertEquals("com.google.inject.spi.Elements",
+ callStack[13].getClassName());
+ assertEquals("com.google.inject.spi.ElementSourceTest",
+ callStack[14].getClassName());
+ // Check modules index
+ List<Integer> indexes = elementSource.getModuleConfigurePositionsInStackTrace();
+ assertEquals((int) indexes.get(0), 4);
+ assertEquals((int) indexes.get(1), 6);
+ assertEquals((int) indexes.get(2), 10);
+ return;
+ }
}
}
}
fail("The test should not reach this line.");
- }
-
- public void testGetCallStack_IntegrationTest_Complete() throws Exception {
- System.setProperty("guice_include_stack_traces", "COMPLETE");
- List<Element> elements = Elements.getElements(new A());
- for (Element element : elements) {
- if (element instanceof Binding) {
- Binding<?> binding = (Binding<?>) element;
- Class<? extends Annotation> annotationType = binding.getKey().getAnnotationType();
- if (annotationType != null && annotationType.equals(SampleAnnotation.class)) {
- ElementSource elementSource = (ElementSource) binding.getSource();
- // Check module stack
- List<String> moduleClassNames = elementSource.getModuleClassNames();
- // Module C
- assertEquals("com.google.inject.spi.ElementSourceTest$C", moduleClassNames.get(0));
- // Module B
- assertEquals("com.google.inject.spi.ElementSourceTest$B", moduleClassNames.get(1));
- // Module A
- assertEquals("com.google.inject.spi.ElementSourceTest$A", moduleClassNames.get(2));
- // Check call stack
- StackTraceElement[] callStack = elementSource.getStackTrace();
- int skippedCallStackSize = new Throwable().getStackTrace().length - 1;
- assertEquals(skippedCallStackSize + 15, elementSource.getStackTrace().length);
- assertEquals("com.google.inject.spi.Elements$RecordingBinder",
- callStack[0].getClassName());
- assertEquals("com.google.inject.spi.Elements$RecordingBinder",
- callStack[1].getClassName());
- assertEquals("com.google.inject.AbstractModule",
- callStack[2].getClassName());
- // Module C
- assertEquals("com.google.inject.spi.ElementSourceTest$C",
- callStack[3].getClassName());
- assertEquals("configure",
- callStack[3].getMethodName());
- assertEquals("Unknown Source",
- callStack[3].getFileName());
- assertEquals("com.google.inject.AbstractModule",
- callStack[4].getClassName());
- assertEquals("com.google.inject.spi.Elements$RecordingBinder",
- callStack[5].getClassName());
- // Module B
- assertEquals("com.google.inject.spi.ElementSourceTest$B",
- callStack[6].getClassName());
- assertEquals("com.google.inject.spi.Elements$RecordingBinder",
- callStack[7].getClassName());
- // Module A
- assertEquals("com.google.inject.AbstractModule",
- callStack[8].getClassName());
- assertEquals("com.google.inject.spi.ElementSourceTest$A",
- callStack[9].getClassName());
- assertEquals("com.google.inject.AbstractModule",
- callStack[10].getClassName());
- assertEquals("com.google.inject.spi.Elements$RecordingBinder",
- callStack[11].getClassName());
- assertEquals("com.google.inject.spi.Elements",
- callStack[12].getClassName());
- assertEquals("com.google.inject.spi.Elements",
- callStack[13].getClassName());
- assertEquals("com.google.inject.spi.ElementSourceTest",
- callStack[14].getClassName());
- // Check modules index
- List<Integer> indexes = elementSource.getModuleConfigurePositionsInStackTrace();
- assertEquals((int) indexes.get(0), 4);
- assertEquals((int) indexes.get(1), 6);
- assertEquals((int) indexes.get(2), 10);
- return;
- }
- }
- }
- fail("The test should not reach this line.");
- }
+ }
private ModuleSource createModuleSource() {
// First module
StackTraceElement[] partialCallStack = new StackTraceElement[1];
- partialCallStack[0] = BINDER_INSTALL;
+ partialCallStack[0] = BINDER_INSTALL;
ModuleSource moduleSource = new ModuleSource(new A(), partialCallStack);
- // Second module
+ // Second module
partialCallStack = new StackTraceElement[2];
partialCallStack[0] = BINDER_INSTALL;
partialCallStack[1] = new StackTraceElement(
"com.google.inject.spi.moduleSourceTest$A", "configure", "Unknown Source", 100);
- moduleSource = moduleSource.createChild(new B(), partialCallStack);
+ moduleSource = moduleSource.createChild(new B(), partialCallStack);
// Third module
partialCallStack = new StackTraceElement[4];
partialCallStack[0] = BINDER_INSTALL;
@@ -168,14 +153,14 @@
install(new B());
}
}
-
+
private static class B implements Module {
@Override
public void configure(Binder binder) {
binder.install(new C());
}
}
-
+
@Retention(RUNTIME)
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@BindingAnnotation
@@ -186,5 +171,5 @@
public void configure() {
bind(String.class).annotatedWith(SampleAnnotation.class).toInstance("the value");
}
- }
+ }
}
diff --git a/core/test/com/google/inject/spi/ElementsTest.java b/core/test/com/google/inject/spi/ElementsTest.java
index 2299e44..e2fcff9 100644
--- a/core/test/com/google/inject/spi/ElementsTest.java
+++ b/core/test/com/google/inject/spi/ElementsTest.java
@@ -18,6 +18,8 @@
import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.inject.Asserts.assertContains;
+import static com.google.inject.Asserts.getDeclaringSourcePart;
+import static com.google.inject.Asserts.isIncludeStackTraceComplete;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import com.google.common.collect.ImmutableMap;
@@ -86,8 +88,9 @@
assertEquals("Message A 5 C", command.getMessage());
assertNull(command.getCause());
assertContains(command.getSources().toString(),
- ElementsTest.class.getName(), ".configure(ElementsTest.java:");
- assertContains(command.getSource(), "ElementsTest.java");
+ ElementsTest.class.getName(),
+ getDeclaringSourcePart(ElementsTest.class));
+ assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
return null;
}
}
@@ -107,7 +110,7 @@
assertEquals("A", command.getCause().getMessage());
assertEquals(command.getMessage(),
"An exception was caught and reported. Message: A");
- assertContains(command.getSource(), "ElementsTest.java");
+ assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
return null;
}
}
@@ -596,7 +599,7 @@
assertEquals("Setting the scope is not permitted when binding to a single instance.",
command.getMessage());
assertNull(command.getCause());
- assertContains(command.getSource(), "ElementsTest.java");
+ assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
return null;
}
}
@@ -913,8 +916,8 @@
one.expose(Collection.class).annotatedWith(SampleAnnotation.class);
one.bind(List.class).to(ArrayList.class);
- PrivateBinder two = binder().withSource("1 ElementsTest.java")
- .newPrivateBinder().withSource("2 ElementsTest.java");
+ PrivateBinder two = binder().withSource("1 FooBar")
+ .newPrivateBinder().withSource("2 FooBar");
two.expose(String.class).annotatedWith(Names.named("a"));
two.expose(b);
two.bind(List.class).to(ArrayList.class);
@@ -936,14 +939,14 @@
}
},
- new FailingElementVisitor() {
+ new ExternalFailureVisitor() {
@Override public Void visit(PrivateElements two) {
assertEquals(ab, two.getExposedKeys());
- assertEquals("1 ElementsTest.java", two.getSource().toString());
+ assertEquals("1 FooBar", two.getSource().toString());
checkElements(two.getElements(),
- new FailingElementVisitor() {
+ new ExternalFailureVisitor() {
@Override public <T> Void visit(Binding<T> binding) {
- assertEquals("2 ElementsTest.java", binding.getSource().toString());
+ assertEquals("2 FooBar", binding.getSource().toString());
assertEquals(Key.get(List.class), binding.getKey());
return null;
}
@@ -976,7 +979,7 @@
assertEquals("More than one annotation is specified for this binding.",
command.getMessage());
assertNull(command.getCause());
- assertContains(command.getSource(), "ElementsTest.java");
+ assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
return null;
}
}
@@ -1003,7 +1006,7 @@
@Override public Void visit(Message command) {
assertEquals("Implementation is set more than once.", command.getMessage());
assertNull(command.getCause());
- assertContains(command.getSource(), "ElementsTest.java");
+ assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
return null;
}
}
@@ -1030,7 +1033,7 @@
@Override public Void visit(Message command) {
assertEquals("Scope is set more than once.", command.getMessage());
assertNull(command.getCause());
- assertContains(command.getSource(), "ElementsTest.java");
+ assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
return null;
}
}
@@ -1058,7 +1061,7 @@
assertEquals("More than one annotation is specified for this binding.",
command.getMessage());
assertNull(command.getCause());
- assertContains(command.getSource(), "ElementsTest.java");
+ assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
return null;
}
}
@@ -1085,7 +1088,7 @@
@Override public Void visit(Message message) {
assertEquals("Constant value is set more than once.", message.getMessage());
assertNull(message.getCause());
- assertContains(message.getSource(), "ElementsTest.java");
+ assertContains(message.getSource(), getDeclaringSourcePart(ElementsTest.class));
return null;
}
}
@@ -1214,7 +1217,6 @@
assertEquals(1, aConfigureCount.get());
}
-
/**
* Ensures the module performs the commands consistent with {@code visitors}.
*/
@@ -1231,11 +1233,14 @@
if (!(element instanceof Message)) {
ElementSource source = (ElementSource) element.getSource();
assertTrue(source.getModuleClassNames().size() > 0);
- assertFalse(source.isStackTraceRetained()) ;
- assertEquals(0, source.getStackTrace().length);
+ if (isIncludeStackTraceComplete()) {
+ assertTrue(source.getStackTrace().length > 0);
+ } else {
+ assertEquals(0, source.getStackTrace().length);
+ }
}
if (!(visitor instanceof ExternalFailureVisitor)) {
- assertContains(element.getSource().toString(), "ElementsTest.java");
+ assertContains(element.getSource().toString(), getDeclaringSourcePart(ElementsTest.class));
}
element.acceptVisitor(visitor);
}
diff --git a/core/test/com/google/inject/spi/SpiBindingsTest.java b/core/test/com/google/inject/spi/SpiBindingsTest.java
index ccf50a9..870c911 100644
--- a/core/test/com/google/inject/spi/SpiBindingsTest.java
+++ b/core/test/com/google/inject/spi/SpiBindingsTest.java
@@ -17,6 +17,8 @@
package com.google.inject.spi;
import static com.google.inject.Asserts.assertContains;
+import static com.google.inject.Asserts.getDeclaringSourcePart;
+import static com.google.inject.Asserts.isIncludeStackTraceComplete;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
@@ -407,11 +409,14 @@
}
public void checkBindingSource(Binding binding) {
- assertContains(binding.getSource().toString(), "SpiBindingsTest.java");
+ assertContains(binding.getSource().toString(), getDeclaringSourcePart(getClass()));
ElementSource source = (ElementSource) binding.getSource();
assertTrue(source.getModuleClassNames().size() > 0);
- assertFalse(source.isStackTraceRetained()) ;
- assertEquals(0, source.getStackTrace().length);
+ if (isIncludeStackTraceComplete()) {
+ assertTrue(source.getStackTrace().length > 0);
+ } else {
+ assertEquals(0, source.getStackTrace().length);
+ }
}
public void checkInjector(Module module, ElementVisitor<?>... visitors) {
diff --git a/pom.xml b/pom.xml
index 9c9b94b..48863a5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -273,6 +273,7 @@
<version>2.5</version>
<configuration>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
+ <!--<argLine>-Dguice_include_stack_traces=OFF</argLine>-->
</configuration>
</plugin>
<!--