Breidenbach, Kevin | 28 Mar 03:27
Favicon

Bug report (with fix) for version 1.0.1

All,
 
I'd like to report a bug (along with a fix). The bug is to do with creation of concrete class mock objects. If the constructor of a class we wish to mock calls a non-private method in that class, the callback from the cglib libraries that causes the following exception:
 
Caused by: org.jmock.core.DynamicMockError: mockDummy: no match found
Invoked: com.bofa.gmtt.jmocktest.classestomock.Dummy.init()
Allowed:
No expectations set
 
I have attached a source code with a unit test that will reproduce the bug. The full outline of the bug is below.
 
While mocking concrete classes is not optimal, and creating classes whose constructors call non-private methods is not necessarily a best-practices, there are many frameworks and libraries that developers need to mock that do have this "feature". JMSTemplate in the Spring 1.2.x library is one of these such classes, and without the fix it is impossible to mock that class.
 
The fix is simple and involves placing a boolean semaphore around the creation of a CGLib proxy that prevents invocation callbacks being acted upon until the class has been created and returned to the test class.
 
The source code is attached, as well as the binary. The source has been tested against the unit and acceptance tests in the JMock 1.0.1 download package.
 
Thanks,
Kevin
 
 
Full description of bug:
 
 
The jmock cglib library allows mocking of concrete classes, however there is a bug in the library that causes an error if the constructor of the class being mocked calls a non-private method within that class. While the best solution for mocking is to use interface/implementation separation, this is an important bug as libraries we would want to mock have constructors that call protected methods (e.g. JMSTemplate in Spring 1.2), which makes it impossible to mock out using JMock. The failure actually occurs on creation of the mock object proxy, where an error occurs stating that there the method call was not expected.
e.g.
 
Class that we want to mock
 
package com.bofa.gmtt.jmocktest.classestomock;

public class Dummy {
 
    private boolean initialized = false;
 
    public Dummy() {
        init();
    }
 
    //This will work if the protection level is increased to private 
    protected void init() {
        System.out.println("Creating Object");
        initialized = true;
    }
 
    /**
     * Pointless method just to give the object something to test with mocking.
     * <at> return whether the object has been initialized.
     */
    public boolean initialized() {
        return initialized;
    }
}
 
Class using the Dummy class
 
package com.bofa.gmtt.jmocktest;
 
import com.bofa.gmtt.jmocktest.classestomock.Dummy;

public class DummyUser {
 
    private final Dummy dummy;
 
    // dependency injected through constructor
    public DummyUser(Dummy dummy) {
        this.dummy = dummy;
    }
 
    public boolean initialized() {
        return dummy.initialized();
    }
}
 
 
Unit test attempting to mock out the Dummy class
 
package com.bofa.gmtt.jmocktest;
import com.bofa.gmtt.jmocktest.classestomock.Dummy;
import org.jmock.Mock;
import org.jmock.cglib.MockObjectTestCase;
 
public class TestDummyUser extends MockObjectTestCase {
 
    private DummyUser dummyUser;
    private Mock dummyMock;
 
    public void setUp() throws Exception {
        // The following line produces the error unless the init method is changed to be a private method
        dummyMock = mock(Dummy.class); // see error line below
        dummyUser = new DummyUser((Dummy) dummyMock.proxy());
    }
 
    public void testInitialized() throws Exception {
        dummyMock.expects(once()).method("initialized").withNoArguments().will(returnValue(true));
        assertTrue(dummyUser.initialized());
    }
}
 
When run this gives the following error, that while at first glances looks like a cglib error, it is actually caused by jmock throwing a DynamicMockError exception - which shouldn't be thrown for this type of error during proxy creation:

net.sf.cglib.core.CodeGenerationException: org.jmock.core.DynamicMockError-->mockDummy: no match found
Invoked: com.bofa.gmtt.jmocktest.classestomock.Dummy.init()
Allowed:
No expectations set
 at net.sf.cglib.core.ReflectUtils.newInstance(ReflectUtils.java:235)
 at net.sf.cglib.core.ReflectUtils.newInstance(ReflectUtils.java:220)
 at net.sf.cglib.core.ReflectUtils.newInstance(ReflectUtils.java:216)
 at net.sf.cglib.proxy.Enhancer.createUsingReflection(Enhancer.java:640)
 at net.sf.cglib.proxy.Enhancer.firstInstance(Enhancer.java:538)
 at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:225)
 at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
 at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)
 at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:660)
 at org.jmock.cglib.CGLIBCoreMock.<init>(Unknown Source)
 at org.jmock.cglib.CGLIBCoreMock.<init>(Unknown Source)
 at org.jmock.cglib.MockObjectTestCase.newCoreMock(Unknown Source)
 at org.jmock.MockObjectTestCase.mock(Unknown Source)
 at org.jmock.MockObjectTestCase.mock(Unknown Source)
 at com.bofa.gmtt.jmocktest.TestDummyUser.setUp(TestDummyUser.java:16)
 at org.jmock.core.VerifyingTestCase.runBare(Unknown Source)
 at com.intellij.rt.execution.junit2.JUnitStarter.main(JUnitStarter.java:32)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
Caused by: org.jmock.core.DynamicMockError: mockDummy: no match found
Invoked: com.bofa.gmtt.jmocktest.classestomock.Dummy.init()
Allowed:
No expectations set
 at org.jmock.core.AbstractDynamicMock.mockInvocation(Unknown Source)
 at org.jmock.cglib.CGLIBCoreMock.intercept(Unknown Source)
 at com.bofa.gmtt.jmocktest.classestomock.Dummy$$EnhancerByCGLIB$$3412a35b.init(<generated>)
 at com.bofa.gmtt.jmocktest.classestomock.Dummy.<init>(Dummy.java:11)
 at com.bofa.gmtt.jmocktest.classestomock.Dummy$$EnhancerByCGLIB$$3412a35b.<init>(<generated>)
 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
 at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
 at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
 at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
 at net.sf.cglib.core.ReflectUtils.newInstance(ReflectUtils.java:228)
 ... 34 more
 

Process finished with exit code -1
 
 
Attachment (JMock_CGLib_Bug.zip): application/x-zip-compressed, 3931 bytes
Jörg Schaible | 28 Mar 08:38

RE: Bug report (with fix) for version 1.0.1

Hi Kevin, 

________________________________

	From: Breidenbach, Kevin 
	Sent: Tuesday, March 28, 2006 3:30 AM
	Subject: [jmock-dev] Bug report (with fix) for version 1.0.1
	
	
	All,
	 
	I'd like to report a bug (along with a fix). The bug is to do with creation of concrete class mock objects. If
the constructor of a class we wish to mock calls a non-private method in that class, the callback from the
cglib libraries that causes the following exception:
	 
	Caused by: org.jmock.core.DynamicMockError: mockDummy: no match found
	Invoked: com.bofa.gmtt.jmocktest.classestomock.Dummy.init()
	Allowed:
	No expectations set
	 
	I have attached a source code with a unit test that will reproduce the bug. The full outline of the bug is below.

[snip]
________________________________

A mailing list might not be the best place to send a patch. Create a JIRA issue and attach it. But it might be
better to check against the head revision of jMock, since this is claimed to be fixed since 9 months already
(http://jira.codehaus.org/browse/JMOCK-75 and http://jira.codehaus.org/browse/JMOCK-37) and
was contributed nearly 2 years ago.

- Jörg

Breidenbach, Kevin | 28 Mar 15:49
Favicon

Re: Bug report (with fix) for version 1.0.1

We were actually using the latest version (1.0.1). I don't see any newer stable versions. Being an
investment bank I don't think we'd be inclined to use a non-stable release.

The bug is definitely in release 1.0.1

I followed instructions on the web-site for submitting bugs. That probably needs updating so people don't
submit bugs to the distribution list. I'll open an issue report.

In the meantime we will use our patched version.

Kevin

-----Original Message-----
From: Jörg Schaible <Joerg.Schaible <at> Elsag-Solutions.com>
To: dev <at> jmock.codehaus.org <dev <at> jmock.codehaus.org>
Sent: Tue Mar 28 01:40:54 2006
Subject: RE: [jmock-dev] Bug report (with fix) for version 1.0.1

Hi Kevin, 

________________________________

	From: Breidenbach, Kevin 
	Sent: Tuesday, March 28, 2006 3:30 AM
	Subject: [jmock-dev] Bug report (with fix) for version 1.0.1
	
	
	All,
	 
	I'd like to report a bug (along with a fix). The bug is to do with creation of concrete class mock objects. If
the constructor of a class we wish to mock calls a non-private method in that class, the callback from the
cglib libraries that causes the following exception:
	 
	Caused by: org.jmock.core.DynamicMockError: mockDummy: no match found
	Invoked: com.bofa.gmtt.jmocktest.classestomock.Dummy.init()
	Allowed:
	No expectations set
	 
	I have attached a source code with a unit test that will reproduce the bug. The full outline of the bug is below.

[snip]
________________________________

A mailing list might not be the best place to send a patch. Create a JIRA issue and attach it. But it might be
better to check against the head revision of jMock, since this is claimed to be fixed since 9 months already
(http://jira.codehaus.org/browse/JMOCK-75 and http://jira.codehaus.org/browse/JMOCK-37) and
was contributed nearly 2 years ago.

- Jörg
Jörg Schaible | 28 Mar 16:24

RE: Bug report (with fix) for version 1.0.1

Hi Kevin,

Breidenbach, Kevin wrote on Tuesday, March 28, 2006 3:51 PM:

> We were actually using the latest version (1.0.1). I don't
> see any newer stable versions. Being an investment bank I
> don't think we'd be inclined to use a non-stable release.
> 
> The bug is definitely in release 1.0.1
> 
> I followed instructions on the web-site for submitting bugs.
> That probably needs updating so people don't submit bugs to
> the distribution list. I'll open an issue report.
> 
> In the meantime we will use our patched version.

This was just a hint if you encounter more problems. jMock 1.0.1 was released roughly 2 years ago and JIRA and
the repository contain a ton of fixes and enhancements. This might save you time.

- Jörg

Breidenbach, Kevin | 28 Mar 17:02
Favicon

Re: Bug report (with fix) for version 1.0.1

Thanks for the reply.

The problem is in the fact that being in an investment bank we are prevented from downloading open-source
the hasn't been cleared. We are also blocked from using CVS to download from external repositories.

I know that JMock was released 2 years ago, we have been using it extensively. But because of our rules (which
many large corporations now have) until the fix you mentioned is in a numbered release (e.g. 1.0.2), we
will not get to use it.

We have the same problem with a number of projects on Codehaus - they do not seem to release numbered versions
as often as other open-source sites.

Do you know when the next numbered version will be available for download?
Kevin E. Breidenbach
Vice President & Principal Architect
Global Markets Trading Technology
Bank of America
231 S La Salle Street
Chicago 60604
312.828.3006


-----Original Message-----
From: Jörg Schaible <Joerg.Schaible <at> Elsag-Solutions.com>
To: dev <at> jmock.codehaus.org <dev <at> jmock.codehaus.org>
Sent: Tue Mar 28 09:27:38 2006
Subject: RE: [jmock-dev] Bug report (with fix) for version 1.0.1

Hi Kevin,

Breidenbach, Kevin wrote on Tuesday, March 28, 2006 3:51 PM:

> We were actually using the latest version (1.0.1). I don't
> see any newer stable versions. Being an investment bank I
> don't think we'd be inclined to use a non-stable release.
> 
> The bug is definitely in release 1.0.1
> 
> I followed instructions on the web-site for submitting bugs.
> That probably needs updating so people don't submit bugs to
> the distribution list. I'll open an issue report.
> 
> In the meantime we will use our patched version.

This was just a hint if you encounter more problems. jMock 1.0.1 was released roughly 2 years ago and JIRA and
the repository contain a ton of fixes and enhancements. This might save you time.

- Jörg
Jörg Schaible | 28 Mar 17:15

RE: Bug report (with fix) for version 1.0.1

Hi Kevin,

Breidenbach, Kevin wrote on Tuesday, March 28, 2006 5:03 PM:

> Thanks for the reply.
> 
> The problem is in the fact that being in an investment bank
> we are prevented from downloading open-source the hasn't been
> cleared. We are also blocked from using CVS to download from external
> repositories. 
> 
> I know that JMock was released 2 years ago, we have been
> using it extensively. But because of our rules (which many
> large corporations now have) until the fix you mentioned is
> in a numbered release (e.g. 1.0.2), we will not get to use it.

Well, we also have meanwhile a complete library with our own add-ons for jMock (still using 1.0.1), that
introduce a lot of the new features. Same boat.

> We have the same problem with a number of projects on
> Codehaus - they do not seem to release numbered versions as
> often as other open-source sites.

Depends on the project. But Codehaus hosts meanwhile quite a lot of inactive projects - unfortunately. Not
that jMock is inactive - they just don't release anything.

> Do you know when the next numbered version will be available for
> download? 

Last time someone asked here on the list was in January ... but don't search the archive, you won't get more
enlightment ;-)

- Jörg

Nat Pryce | 31 Mar 15:14

Re: Bug report (with fix) for version 1.0.1

Yes yes... we know, we know.  The thing is, it takes time to apply the
patches and clean up the code, and performing a release takes even
longer.  We're all independent developers and jMock doesn't pay the
bills.  Or rather, investment banks that use jMock don't pay the
bills.

We've been talking about releasing an Enterprise version of jMock that
would be a stable, binaries only release and cost several thousand
dollars per developer seat, or 100,000 dollars for an enterprise-wide
site license.  For that money, you'd get support and a shiny round
version number and not get to see the source.

For true enterprise quality, we could even make the documentation
misleading and add some bugs.

Any takers?

--Nat.

On 3/28/06, Jörg Schaible <Joerg.Schaible@...> wrote:
> Hi Kevin,
>
> Breidenbach, Kevin wrote on Tuesday, March 28, 2006 5:03 PM:
>
> > Thanks for the reply.
> >
> > The problem is in the fact that being in an investment bank
> > we are prevented from downloading open-source the hasn't been
> > cleared. We are also blocked from using CVS to download from external
> > repositories.
> >
> > I know that JMock was released 2 years ago, we have been
> > using it extensively. But because of our rules (which many
> > large corporations now have) until the fix you mentioned is
> > in a numbered release (e.g. 1.0.2), we will not get to use it.
>
> Well, we also have meanwhile a complete library with our own add-ons for jMock (still using 1.0.1), that
introduce a lot of the new features. Same boat.
>
> > We have the same problem with a number of projects on
> > Codehaus - they do not seem to release numbered versions as
> > often as other open-source sites.
>
> Depends on the project. But Codehaus hosts meanwhile quite a lot of inactive projects - unfortunately.
Not that jMock is inactive - they just don't release anything.
>
> > Do you know when the next numbered version will be available for
> > download?
>
> Last time someone asked here on the list was in January ... but don't search the archive, you won't get more
enlightment ;-)
>
> - Jörg
>

Jörg Schaible | 1 Apr 11:51

Re: Bug report (with fix) for version 1.0.1

Hi Nat,

Nat Pryce wrote:

> Yes yes... we know, we know.  The thing is, it takes time to apply the
> patches and clean up the code, and performing a release takes even
> longer.  We're all independent developers and jMock doesn't pay the
> bills.  Or rather, investment banks that use jMock don't pay the
> bills.

Also same boat, a lot of my spare time is dedicated to open source
development. But it is as Kevin said, OSS is a community effort and in the
last 2 years I have seen quite some people, that put some real effort into
jMock enhancements or development. Waiting for ages for a new release *is*
frustrating.

> We've been talking about releasing an Enterprise version of jMock that
> would be a stable, binaries only release and cost several thousand
> dollars per developer seat, or 100,000 dollars for an enterprise-wide
> site license.  For that money, you'd get support and a shiny round
> version number and not get to see the source.
>
> For true enterprise quality, we could even make the documentation
> misleading and add some bugs.
> 
> Any takers?

I worked already with software of Segue and Mercury - so, thanks, no.

- Jörg

Breidenbach, Kevin | 31 Mar 16:21
Favicon

Re: Bug report (with fix) for version 1.0.1

I believe that we may be interested in a commercial supported version, but would still want the source code
(same as the JIRA / Confluence model)

Alternatively you could open youselves up to allowing more contributors - there are several willing
participants here!



-----Original Message-----
From: Nat Pryce <nat.pryce <at> gmail.com>
To: dev <at> jmock.codehaus.org <dev <at> jmock.codehaus.org>
Sent: Fri Mar 31 08:14:25 2006
Subject: Re: [jmock-dev] Bug report (with fix) for version 1.0.1

Yes yes... we know, we know.  The thing is, it takes time to apply the
patches and clean up the code, and performing a release takes even
longer.  We're all independent developers and jMock doesn't pay the
bills.  Or rather, investment banks that use jMock don't pay the
bills.

We've been talking about releasing an Enterprise version of jMock that
would be a stable, binaries only release and cost several thousand
dollars per developer seat, or 100,000 dollars for an enterprise-wide
site license.  For that money, you'd get support and a shiny round
version number and not get to see the source.

For true enterprise quality, we could even make the documentation
misleading and add some bugs.

Any takers?

--Nat.


On 3/28/06, Jörg Schaible <Joerg.Schaible <at> elsag-solutions.com> wrote:
> Hi Kevin,
>
> Breidenbach, Kevin wrote on Tuesday, March 28, 2006 5:03 PM:
>
> > Thanks for the reply.
> >
> > The problem is in the fact that being in an investment bank
> > we are prevented from downloading open-source the hasn't been
> > cleared. We are also blocked from using CVS to download from external
> > repositories.
> >
> > I know that JMock was released 2 years ago, we have been
> > using it extensively. But because of our rules (which many
> > large corporations now have) until the fix you mentioned is
> > in a numbered release (e.g. 1.0.2), we will not get to use it.
>
> Well, we also have meanwhile a complete library with our own add-ons for jMock (still using 1.0.1), that
introduce a lot of the new features. Same boat.
>
> > We have the same problem with a number of projects on
> > Codehaus - they do not seem to release numbered versions as
> > often as other open-source sites.
>
> Depends on the project. But Codehaus hosts meanwhile quite a lot of inactive projects - unfortunately.
Not that jMock is inactive - they just don't release anything.
>
> > Do you know when the next numbered version will be available for
> > download?
>
> Last time someone asked here on the list was in January ... but don't search the archive, you won't get more
enlightment ;-)
>
> - Jörg
>

Gmane