Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

InvocationTargetException testing partial entities #35

Closed
paulhoadley opened this issue Feb 25, 2014 · 8 comments
Closed

InvocationTargetException testing partial entities #35

paulhoadley opened this issue Feb 25, 2014 · 8 comments
Assignees

Comments

@paulhoadley
Copy link

This is similar to the issue I reported in #32 (in that it occurs with the exact same test I described there), but it's a different looking stack trace now.

I may have contributed to some confusion here, in that I pulled the test described in #32 from my test suite altogether, and then described a different partials-related problem (whereby attributes added by the augmented entities weren't being recognised as merged into the base entity) which was completely fixed in the recent 1.2.3 release.

What I'm seeing now is an InvocationTargetException trying to test the base class at the framework level. I'll reproduce here the code from #32, as it's the same:

public class UserTest {
    @Rule
    public MockEditingContext ec = new MockEditingContext("Ident");

    @Test
    public void createUser() {
        User u = User.createUser(ec, "password", "username");
        confirm(u, canBeSaved());
        return;
    }
}

Worse, the problem is non-deterministic: sometimes this test will pass, sometimes it will fail. When it fails, this is the current stack trace:

com.webobjects.foundation.NSForwardException [java.lang.reflect.InvocationTargetException] null:java.lang.reflect.InvocationTargetException
    at com.webobjects.foundation._NSUtilities._explainInstantiationException(_NSUtilities.java:626)
    at com.webobjects.foundation._NSUtilities.instantiateObjectWithConstructor(_NSUtilities.java:665)
    at com.webobjects.eoaccess.EOEntityClassDescription.createInstanceWithEditingContext(EOEntityClassDescription.java:242)
    at com.webobjects.eoaccess.EOUtilities.createAndInsertInstance(EOUtilities.java:861)
    at com.wounit.rules.AbstractEditingContextRule$UnderTestFacade.create(AbstractEditingContextRule.java:72)
    at com.wounit.rules.AnnotationProcessor.createEOForType(AnnotationProcessor.java:49)
    at com.wounit.rules.AnnotationProcessor.initializeObject(AnnotationProcessor.java:172)
    at com.wounit.rules.AnnotationProcessor.process(AnnotationProcessor.java:205)
    at com.wounit.rules.AbstractEditingContextRule.before(AbstractEditingContextRule.java:182)
    at com.wounit.rules.MockEditingContext.before(MockEditingContext.java:147)
    at com.wounit.rules.AbstractEditingContextRule$1.evaluate(AbstractEditingContextRule.java:162)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.reflect.InvocationTargetException
    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:513)
    at com.webobjects.foundation._NSUtilities.instantiateObjectWithConstructor(_NSUtilities.java:659)
    ... 24 more
Caused by: java.lang.NullPointerException
    at com.webobjects.eoaccess.EOModel.createPrototypeCache(EOModel.java:631)
    at com.webobjects.eoaccess.EOModel.prototypeAttributeNamed(EOModel.java:699)
    at com.webobjects.eoaccess.ERXModel.prototypeAttributeNamed(ERXModel.java:290)
    at com.webobjects.eoaccess.EOAttribute.<init>(EOAttribute.java:998)
    at com.webobjects.eoaccess.EOEntity.attributes(EOEntity.java:816)
    at com.webobjects.eoaccess.EOEntity.attributeNamed(EOEntity.java:789)
    at com.webobjects.eoaccess.EOEntity.classProperties(EOEntity.java:1098)
    at com.webobjects.eoaccess.EOEntity._propertyDictionaryInitializer(EOEntity.java:3321)
    at com.webobjects.eoaccess.EOEntity._newDictionaryForProperties(EOEntity.java:3667)
    at com.webobjects.eoaccess.EOEntityClassDescription._newDictionaryForProperties(EOEntityClassDescription.java:88)
    at com.webobjects.eocontrol.EOGenericRecord.__setClassDescription(EOGenericRecord.java:111)
    at com.webobjects.eocontrol.EOGenericRecord.__setClassDescription(EOGenericRecord.java:100)
    at com.webobjects.eocontrol.EOGenericRecord.<init>(EOGenericRecord.java:73)
    at er.extensions.eof.ERXGenericRecord.<init>(ERXGenericRecord.java:103)
    at er.extensions.partials.ERXPartialGenericRecord.<init>(ERXPartialGenericRecord.java:28)
    at net.logicsquad.access.model._User.<init>(_User.java:20)
    at net.logicsquad.access.model.User.<init>(User.java:14)
    ... 29 more

Note that that is different to the stack trace in #32.

So, to re-iterate, 1.2.3 completely solves the initialisation-related issue with merging of properties down to the base class. But the problem of testing just the base classes seems to persist.

Henrique, I'm going to send you my framework and its tests out of band in the hope you can pinpoint the problem quickly.

@hprange
Copy link
Owner

hprange commented Mar 1, 2014

Are there any chances these tests are running in parallel?

@paulhoadley
Copy link
Author

As we've subsequently discussed in email, no it's just a single test method. (Also, this is running within Eclipse—is there a way to set JUnit concurrency within Eclipse?) If you end up adding the locking mechanism you talked about elsewhere, I'll see if that has any effect, though presumably that would only help if parallel testing was the problem, and in this case it can't be, right?

@hprange hprange self-assigned this Mar 14, 2014
@hprange
Copy link
Owner

hprange commented Mar 14, 2014

I've reproduced it! I'm looking for a solution. I think the clue is in this log statement:

- Entity classDescription is not ERXEntityClassDescription: Login
- Entity classDescription is not ERXEntityClassDescription: User
- Entity classDescription is not ERXEntityClassDescription: UserRole

It appears only if the test throws the mentioned exception.

@paulhoadley
Copy link
Author

Great news Henrique. Let me know if there's anything I can do to help.

hprange added a commit to hprange/wonder that referenced this issue Mar 15, 2014
…che method from the wrong EOModel

The `ERXModelGroup` class may create duplicate models in some cases. They are not added to the model group, but their presence may cause problems. The root cause of this problem is related to the duplication of `NSBundle` references while loading `EOModel`s. This fix uses a `NSMutableSet` instead of a `NSMutableArray` to hold the references to all loaded bundles. It avoids the presence of duplicate bundles and therefore the presence of duplicate model references.

One can find more information about the issue at the above link.

hprange/wounit#35
@hprange
Copy link
Owner

hprange commented Mar 15, 2014

I've found the root cause of the problem. Unfortunately, its a bug in Project Wonder. I'm not sure I can do something on WOUnit to workaround this problem.

I've added a few log messages to ERXModel and ERXModelGroup classes. The numbers in parenthesis are the hash code value for each object.

1. Add model erprototypes (322185831) to the default model group
2. Add model Control (429231097) to the default model group
3. Add model Ident (817101240) to the default model group
4. Refuse to add duplicate model Control (689037010) to the default model group
5. Refuse to add duplicate model Ident (1413202446) to the default model group
6. Load attribute prototype named from model Ident (817101240)
7. Load attribute prototype named from model Control (429231097)
8. Load attribute prototype named from model Ident (1413202446)

Pay attention to lines 5 and 8. At line 5, the model group refuses to load the model Ident with hash code 1413202446 because there's already one model Ident loaded. However, an attribute prototype is loaded from the Ident model 1413202446 at line 8 only if the test throws the mentioned exception. The line 8 doesn't appear when the test pass.

I have no idea why the prototype is loaded from the wrong model. In spite of that fact, I know how to fix the Wonder code to avoid the creation of duplicate models. I've created the pull request wocommunity/wonder#551 as an attempt to solve this problem. Would you mind to try it?

@paulhoadley
Copy link
Author

I will test it out, yes. Give me a couple of days.

@paulhoadley
Copy link
Author

The ERXModelGroup patch in wocommunity/wonder#551 completely fixes this issue for me.

@paulhoadley
Copy link
Author

I should have closed this back in March. The fix to ERXModelGroup referred to above completely resolves this for me. (I just updated Wonder to 6.1.2 locally, which fixed these tests on partial entities for me, which reminded me to go close this issue. Sorry it stayed open so long, there was no need.)

johnthuss pushed a commit to johnthuss/wonder that referenced this issue May 12, 2016
…che method from the wrong EOModel

The `ERXModelGroup` class may create duplicate models in some cases. They are not added to the model group, but their presence may cause problems. The root cause of this problem is related to the duplication of `NSBundle` references while loading `EOModel`s. This fix uses a `NSMutableSet` instead of a `NSMutableArray` to hold the references to all loaded bundles. It avoids the presence of duplicate bundles and therefore the presence of duplicate model references.

One can find more information about the issue at the above link.

hprange/wounit#35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants