Skip to content

Instantly share code, notes, and snippets.

@tobyweston
Created May 31, 2012 08:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tobyweston/2841959 to your computer and use it in GitHub Desktop.
Save tobyweston/2841959 to your computer and use it in GitHub Desktop.
Avoid finalizer problems with JMocks SingleThreadedPolicy
public static class SingleThreadedPolicyAvoidingFinaliseProblems extends SingleThreadedPolicy {
@Override
public Invokable synchroniseAccessTo(final Invokable mockObject) {
final Invokable synchronizedMockObject = super.synchroniseAccessTo(mockObject);
return new Invokable() {
@Override
public Object invoke(Invocation invocation) throws Throwable {
if (Thread.currentThread().getName().equalsIgnoreCase("Finalizer"))
return mockObject.invoke(invocation);
return synchronizedMockObject.invoke(invocation);
}
};
}
}
@tobyweston
Copy link
Author

Avoid's spurious errors like the following, where the synchroniser is correctly detecting invocation to a mockery but for some reason, this is from a finalizer thread (and so not really a genuine error).

2012-05-31 08:35:35,283 ERROR Finalizer [Console$Logger] - the Mockery is not thread-safe: use a Synchroniser to ensure thread safety

See bug report JMOCK-256 and on Github #36

@tobyweston
Copy link
Author

Bit of an improvment

public static class SingleThreadedPolicyAvoidingFinaliseProblems extends SingleThreadedPolicy {
    @Override
    public Invokable synchroniseAccessTo(Invokable unsynchronizedInvocation) {
        Invokable synchronizedInvocation = super.synchroniseAccessTo(unsynchronizedInvocation);
        return new InvokeBasedOnCurrentThreadBeingTheFinalizerThread(unsynchronizedInvocation, synchronizedInvocation);
    }
}

private static class InvokeBasedOnCurrentThreadBeingTheFinalizerThread implements Invokable {

    private final Invokable whenOnFinalizerThread;
    private final Invokable whenNotFinalizerThread;

    public InvokeBasedOnCurrentThreadBeingTheFinalizerThread(Invokable whenOnFinalizerThread, Invokable whenNotFinalizerThread) {
        this.whenOnFinalizerThread = whenOnFinalizerThread;
        this.whenNotFinalizerThread = whenNotFinalizerThread;
    }

    @Override
    public Object invoke(Invocation invocation) throws Throwable {
        if (currentThreadIs("Finalizer"))
            return whenOnFinalizerThread.invoke(invocation);
        return whenNotFinalizerThread.invoke(invocation);
    }

    private static boolean currentThreadIs(String name) {
        return Thread.currentThread().getName().equalsIgnoreCase(name);
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment