|
|
|
Re: JvmModelInferrer refer to a java class not in the model [message #1005771 is a reply to message #759385] |
Mon, 28 January 2013 16:43 |
Alan Alberghini Messages: 19 Registered: January 2013 |
Junior Member |
|
|
I keep incurring in strange behavior with TypeReferences injected instances...
I'm trying to add Junit4 annotations to a couple of methods inside my inferrer and, as a test, I tried two "semantically equivalent" paths but with different results.
In my inferrer I have:
class TestInferrer {
@Inject extension JvmTypesBuilder
@Inject TypesFactory typesFactory
@Inject TypeReferences typeRefs
private JvmUtils jvmUtils
/**
* Infers TestSpec to Junit4 test classes
* @param testSpec The TestSpec object containing the test specifcation for an Entity
* @param acceptor the IAcceptor used to infer the model
*/
def infer (TestSpec testSpec, IAcceptor<JvmDeclaredType> acceptor) {
jvmUtils = JvmUtils::instance
acceptor.accept (testSpec.toClass(getNameForTestClass(testSpec.entity))[
it.documentation = "Test class for Entity " + testSpec.entity.name
[...]
/*
* setUp / tearDown implementation
*/
if (testSpec.setupBody != null)
members += testSpec.toMethod("setUp", testSpec.newTypeRef("void"))[
it.body = testSpec.setupBody
var anno = jvmUtils.getAnnotationReference(typeof(org.junit.Before), testSpec.entity)
if (anno != null)
it.annotations += anno
]
[...]
/*
* Map every Test to a test method
*/
for (test: testSpec.testCases){
members += test.toMethod(test.name, test.newTypeRef("void")) [
var annotation = typesFactory.createJvmAnnotationReference
annotation.annotation = typeRefs.findDeclaredType(typeof(org.junit.Test), testSpec.entity) as JvmAnnotationType
it.annotations += annotation
it.body = test.body
]
}
])
}
}
while the code inside JvmUtil to get an annotation reference is:
class JvmUtils {
@Inject TypeReferences typeRefs
def getAnnotationReference (Class<?> annotationClass, EObject context){
if (!annoRefs.containsKey(annotationClass.name)){
if (typeRefs == null)
typeRefs = new TypeReferences()
var temp = TypesFactory::eINSTANCE.createJvmAnnotationReference
temp.annotation = typeRefs.findDeclaredType(annotationClass, context) as JvmAnnotationType
annoRefs.put(annotationClass.name, temp)
}
annoRefs.get(annotationClass.name)
}
Using the utility I wrote inside JvmUtils I keep getting NullPointerExceptions because typeRefs is null and manually instantiating it results in the TypeFactory inside typeRefs to be null.
The code inside the TestInferrer class getting a reference for the "@Test" annotation works flawlessly, instead.
How come the two "semantically equivalent" code paths behave differently? Am I doing something wrong with Guice's injection?
|
|
|
Re: JvmModelInferrer refer to a java class not in the model [message #1005807 is a reply to message #1005771] |
Mon, 28 January 2013 19:49 |
|
But JvmUtils is not injected, that's why you get null pointer
exceptions, as far as I understand...
On 01/28/2013 05:43 PM, Alan Alberghini wrote:
> I keep incurring in strange behavior with TypeReferences injected
> instances...
> I'm trying to add Junit4 annotations to a couple of methods inside my
> inferrer and, as a test, I tried two "semantically equivalent" paths but
> with different results.
> In my inferrer I have:
>
> class TestInferrer {
>
> @Inject extension JvmTypesBuilder
>
> @Inject TypesFactory typesFactory
> @Inject TypeReferences typeRefs
>
> private JvmUtils jvmUtils
>
> /**
> * Infers TestSpec to Junit4 test classes
> * @param testSpec The TestSpec object containing the test
> specifcation for an Entity
> * @param acceptor the IAcceptor used to infer the model
> */
>
> def infer (TestSpec testSpec, IAcceptor<JvmDeclaredType> acceptor) {
> jvmUtils = JvmUtils::instance
> acceptor.accept
> (testSpec.toClass(getNameForTestClass(testSpec.entity))[
>
> it.documentation = "Test class for Entity " +
> testSpec.entity.name
>
> [...]
> /*
> * setUp / tearDown implementation
> */
> if (testSpec.setupBody != null)
> members += testSpec.toMethod("setUp",
> testSpec.newTypeRef("void"))[
> it.body = testSpec.setupBody
> var anno =
> jvmUtils.getAnnotationReference(typeof(org.junit.Before), testSpec.entity)
> if (anno != null)
> it.annotations += anno ]
>
> [...]
> /*
> * Map every Test to a test method
> */
>
> for (test: testSpec.testCases){
> members += test.toMethod(test.name,
> test.newTypeRef("void")) [
> var annotation =
> typesFactory.createJvmAnnotationReference
> annotation.annotation =
> typeRefs.findDeclaredType(typeof(org.junit.Test), testSpec.entity) as
> JvmAnnotationType
> it.annotations += annotation
> it.body = test.body
> ]
> }
>
> ])
> }
> }
>
> while the code inside JvmUtil to get an annotation reference is:
>
> class JvmUtils {
>
> @Inject TypeReferences typeRefs
>
> def getAnnotationReference (Class<?> annotationClass, EObject context){
> if (!annoRefs.containsKey(annotationClass.name)){
> if (typeRefs == null)
> typeRefs = new TypeReferences()
> var temp = TypesFactory::eINSTANCE.createJvmAnnotationReference
> temp.annotation = typeRefs.findDeclaredType(annotationClass,
> context) as JvmAnnotationType
> annoRefs.put(annotationClass.name, temp)
> }
> annoRefs.get(annotationClass.name)
> }
>
> Using the utility I wrote inside JvmUtils I keep getting
> NullPointerExceptions because typeRefs is null and manually
> instantiating it results in the TypeFactory inside typeRefs to be null.
> The code inside the TestInferrer class getting a reference for the
> "@Test" annotation works flawlessly, instead.
> How come the two "semantically equivalent" code paths behave
> differently? Am I doing something wrong with Guice's injection?
--
Lorenzo Bettini, PhD in Computer Science, DI, Univ. Torino
HOME: http://www.lorenzobettini.it
HOME: http://www.lorenzobettini.it
TDD Book: https://leanpub.com/tdd-buildautomation-ci
Xtext Book: https://www.packtpub.com/application-development/implementing-domain-specific-languages-xtext-and-xtend-second-edition
|
|
|
|
|
|
|
Re: JvmModelInferrer refer to a java class not in the model [message #1005838 is a reply to message #1005833] |
Mon, 28 January 2013 23:01 |
Alan Alberghini Messages: 19 Registered: January 2013 |
Junior Member |
|
|
I chose the "singleton way" because I preferred it over a bunch of static fields/methods to share some common data across inferrers, but it didn't work either in a static only environment.
I originally thought that injecting a static TypeReferences field didn't work for some reason, but now I see that it isn't working in a non-static environment too.
Am I under completely wrong assumptions about how I should create a new TypeReferences instance?
UPDATE:
I now bypassed the problem by passing the typeRefs instance from the TestInferrer class to JvmUtils and exploited the EcoreUtil2.cloneWithProxies() method on the returned JvmAnnotationReference, but I would still like to understand why the injected TypeReferences instance is created correctly inside TestInferrer but not in JvmUtils.
Any insight?
UPDATE2:
I now added another method to get a JvmTypeReference out of one of my domain elements (Entity). For this I'm using the newTypeRef method found in JvmTypesBuilder, which is injected in the JvmUtils class with:
@Inject extension JvmTypesBuilder
Obviously (not to me, but I'm not so shocked anymore by it...), the associated instance is never initialized, resulting in several NullPointerExceptions when trying to extract a JvmTypeReference from a String.
I can't really seem to get the hang of it...
[Updated on: Tue, 29 January 2013 14:43] Report message to a moderator
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.05398 seconds