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

Should be possible to customize model transformation (Transformation is not @ChainOverridable) #64

Open
kamaladafrica opened this issue Nov 28, 2013 · 10 comments
Assignees

Comments

@kamaladafrica
Copy link

In the version before, this was done through AOP advices in the file src/main/resources/extensions/SpecialCases.ext, like in the following snippet:

import sculptormetamodel;

around transformation::Transformation::modifyUuid(DomainObject domainObject) :
    null;
@tjuerge
Copy link
Member

tjuerge commented Nov 29, 2013

Adding the ChainOverridable annotation to the transformations produces strange exceptions in Xtext, e.g.

22:06:53.732 [main] DEBUG o.s.g.c.ChainOverridableProcessor - Processing class 'org.sculptor.generator.transform.DslTransformation'
22:06:53.736 [main] DEBUG o.s.g.c.ChainOverridableProcessor - Transforming annotated class 'org.sculptor.generator.transform.DslTransformation'
[ERROR] resolution of uriFragment '|64' failed.
org.eclipse.emf.common.util.WrappedException: java.lang.NullPointerException
    at org.eclipse.xtext.util.OnChangeEvictingCache.execWithoutCacheClear(OnChangeEvictingCache.java:129)
    at org.eclipse.xtext.xbase.typesystem.internal.CachingBatchTypeResolver.resolveTypes(CachingBatchTypeResolver.java:58)
    at org.eclipse.xtext.xbase.resource.BatchLinkingService.resolveBatched(BatchLinkingService.java:40)
    at org.eclipse.xtext.xbase.resource.BatchLinkableResource.getEObject(BatchLinkableResource.java:98)
    at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.getEObject(ResourceSetImpl.java:223)
    at org.eclipse.emf.ecore.util.EcoreUtil.resolve(EcoreUtil.java:198)
    at org.eclipse.emf.ecore.util.EcoreUtil.resolve(EcoreUtil.java:258)
    at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eResolveProxy(BasicEObjectImpl.java:1473)
    at org.eclipse.xtext.xbase.impl.XAbstractFeatureCallImpl.getFeature(XAbstractFeatureCallImpl.java:163)
    at org.eclipse.xtext.xbase.impl.XAbstractFeatureCallImpl.eGet(XAbstractFeatureCallImpl.java:478)
    at org.eclipse.xtext.xbase.impl.XMemberFeatureCallImpl.eGet(XMemberFeatureCallImpl.java:457)
    at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjectImpl.java:1011)
    at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjectImpl.java:1003)
    at org.eclipse.emf.ecore.util.EContentsEList$FeatureIteratorImpl.hasNext(EContentsEList.java:403)
    at org.eclipse.emf.ecore.util.EcoreUtil.resolveCrossReferences(EcoreUtil.java:303)
    at org.eclipse.emf.ecore.util.EcoreUtil.resolveAll(EcoreUtil.java:297)
    at org.eclipse.emf.ecore.util.EcoreUtil.resolveAll(EcoreUtil.java:282)
    at org.eclipse.emf.ecore.util.EcoreUtil.resolveAll(EcoreUtil.java:270)
    at org.eclipse.xtend.core.compiler.batch.XtendBatchCompiler.compile(XtendBatchCompiler.java:291)
    at org.eclipse.xtend.maven.AbstractXtendCompilerMojo.compile(AbstractXtendCompilerMojo.java:109)
    at org.eclipse.xtend.maven.XtendCompile.compileSources(XtendCompile.java:66)
    at org.eclipse.xtend.maven.XtendCompile.internalExecute(XtendCompile.java:59)
    at org.eclipse.xtend.maven.AbstractXtendMojo.execute(AbstractXtendMojo.java:39)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: java.lang.NullPointerException
    at org.eclipse.xtend.core.typesystem.DispatchAndExtensionAwareReentrantTypeResolver$CreateCacheFieldTypeReferenceProvider.doGetTypeReference(DispatchAndExtensionAwareReentrantTypeResolver.java:254)
    at org.eclipse.xtext.xbase.typesystem.util.AbstractReentrantTypeReferenceProvider.getTypeReference(AbstractReentrantTypeReferenceProvider.java:28)
    at org.eclipse.xtext.xtype.impl.XComputedTypeReferenceImplCustom.getEquivalent(XComputedTypeReferenceImplCustom.java:46)
    at org.eclipse.xtext.xbase.typesystem.references.OwnedConverter.doVisitComputedTypeReference(OwnedConverter.java:131)
    at org.eclipse.xtext.xbase.typesystem.references.OwnedConverter.doVisitComputedTypeReference(OwnedConverter.java:1)
    at org.eclipse.xtext.xtype.impl.XComputedTypeReferenceImplCustom.accept(XComputedTypeReferenceImplCustom.java:27)
    at org.eclipse.xtext.common.types.util.AbstractTypeReferenceVisitor.visit(AbstractTypeReferenceVisitor.java:32)
    at org.eclipse.xtext.common.types.util.AbstractTypeReferenceVisitor.doVisitSpecializedTypeReference(AbstractTypeReferenceVisitor.java:46)
    at org.eclipse.xtext.xtype.util.AbstractXtypeReferenceVisitor.doVisitComputedTypeReference(AbstractXtypeReferenceVisitor.java:24)
    at org.eclipse.xtext.xbase.typesystem.references.OwnedConverter.doVisitComputedTypeReference(OwnedConverter.java:134)
    at org.eclipse.xtext.xbase.typesystem.references.OwnedConverter.doVisitComputedTypeReference(OwnedConverter.java:1)
    at org.eclipse.xtext.xtype.impl.XComputedTypeReferenceImplCustom.accept(XComputedTypeReferenceImplCustom.java:27)
    at org.eclipse.xtext.common.types.util.AbstractTypeReferenceVisitor.visit(AbstractTypeReferenceVisitor.java:32)
    at org.eclipse.xtext.xbase.typesystem.references.OwnedConverter.toLightweightReference(OwnedConverter.java:75)
    at org.eclipse.xtext.xbase.typesystem.internal.FieldTypeComputationState.createNoTypeResult(FieldTypeComputationState.java:54)
    at org.eclipse.xtext.xbase.typesystem.internal.AbstractRootTypeComputationState.computeTypes(AbstractRootTypeComputationState.java:35)
    at org.eclipse.xtext.xbase.typesystem.internal.LogicalContainerAwareReentrantTypeResolver._computeTypes(LogicalContainerAwareReentrantTypeResolver.java:455)
    at org.eclipse.xtext.xbase.typesystem.internal.LogicalContainerAwareReentrantTypeResolver.computeTypes(LogicalContainerAwareReentrantTypeResolver.java:420)
    at org.eclipse.xtext.xbase.typesystem.internal.LogicalContainerAwareReentrantTypeResolver.computeMemberTypes(LogicalContainerAwareReentrantTypeResolver.java:583)
    at org.eclipse.xtext.xbase.typesystem.internal.LogicalContainerAwareReentrantTypeResolver._computeTypes(LogicalContainerAwareReentrantTypeResolver.java:572)
    at org.eclipse.xtext.xbase.typesystem.internal.LogicalContainerAwareReentrantTypeResolver.computeTypes(LogicalContainerAwareReentrantTypeResolver.java:416)
    at org.eclipse.xtext.xbase.typesystem.internal.LogicalContainerAwareReentrantTypeResolver.computeTypes(LogicalContainerAwareReentrantTypeResolver.java:411)
    at org.eclipse.xtend.core.typesystem.DispatchAndExtensionAwareReentrantTypeResolver.computeTypes(DispatchAndExtensionAwareReentrantTypeResolver.java:283)
    at org.eclipse.xtext.xbase.typesystem.internal.DefaultReentrantTypeResolver.resolve(DefaultReentrantTypeResolver.java:210)
    at org.eclipse.xtext.xbase.typesystem.internal.DefaultReentrantTypeResolver.reentrantResolve(DefaultReentrantTypeResolver.java:197)
    at org.eclipse.xtext.xbase.typesystem.internal.TypeResolutionStateAdapter.reentrantResolve(TypeResolutionStateAdapter.java:82)
    at org.eclipse.xtext.xbase.typesystem.internal.CompoundReentrantTypeResolver.reentrantResolve(CompoundReentrantTypeResolver.java:65)
    at org.eclipse.xtext.xbase.typesystem.internal.CachingBatchTypeResolver$LazyResolvedTypes.delegate(CachingBatchTypeResolver.java:114)
    at org.eclipse.xtext.xbase.typesystem.internal.CachingBatchTypeResolver$2.process(CachingBatchTypeResolver.java:61)
    at org.eclipse.xtext.xbase.typesystem.internal.CachingBatchTypeResolver$2.process(CachingBatchTypeResolver.java:1)
    at org.eclipse.xtext.util.concurrent.IUnitOfWork$Void.exec(IUnitOfWork.java:36)
    at org.eclipse.xtext.util.OnChangeEvictingCache.execWithoutCacheClear(OnChangeEvictingCache.java:127)
    ... 43 more
22:06:53.810 [main] DEBUG o.s.g.c.ChainOverridableProcessor - Processing class 'org.sculptor.generator.transform.RestTransformation'
22:06:53.811 [main] DEBUG o.s.g.c.ChainOverridableProcessor - Transforming annotated class 'org.sculptor.generator.transform.RestTransformation'
[ERROR]
ERROR:  DslTransformation.xtend - /Users/torsten/Develop/git/sculptor/sculptor-generator/sculptor-generator-core/src/main/java/org/sculptor/generator/transform/DslTransformation.xtend
86: Error during annotation processing:
org.eclipse.emf.common.util.WrappedException: java.lang.NullPointerException
    at org.eclipse.xtext.util.OnChangeEvictingCache.execWithoutCacheClear(OnChangeEvictingCache.java:129)

The culprit are the public methods with the caching keyword "create". After changing their scope to private (to skip them by the OverrideAnnotationProcessor) results in invalid generated Java code, e.g. missing method parameters.

@tavoda
Copy link
Member

tavoda commented Nov 29, 2013

But for Transformation.xtend it's working for me. Only DslTransformation and Rest are firing this error.

@rcodesmith
Copy link
Member

It looks like there's a bug with create methods and active annotation processing. I posted a question here:
https://groups.google.com/forum/#!topic/xtend-lang/ePkoY6TebhI

NPE is triggered when it tries to call getReturnType() on method:

org.eclipse.emf.common.util.WrappedException: java.lang.NullPointerException
    at org.eclipse.xtext.util.OnChangeEvictingCache.execWithoutCacheClear(OnChangeEvictingCache.java:129)
    at org.eclipse.xtext.xbase.typesystem.internal.CachingBatchTypeResolver.resolveTypes(CachingBatchTypeResolver.java:58)
    at org.eclipse.xtext.xbase.typesystem.InferredTypeIndicator.getTypeReference(InferredTypeIndicator.java:72)
    at org.eclipse.xtext.xtype.impl.XComputedTypeReferenceImplCustom.getEquivalent(XComputedTypeReferenceImplCustom.java:46)
    at org.eclipse.xtext.xbase.typesystem.references.OwnedConverter.doVisitComputedTypeReference(OwnedConverter.java:131)
    at org.eclipse.xtext.xbase.typesystem.references.OwnedConverter.doVisitComputedTypeReference(OwnedConverter.java:1)
    at org.eclipse.xtext.xtype.impl.XComputedTypeReferenceImplCustom.accept(XComputedTypeReferenceImplCustom.java:27)
    at org.eclipse.xtext.common.types.util.AbstractTypeReferenceVisitor.visit(AbstractTypeReferenceVisitor.java:32)
    at org.eclipse.xtext.xbase.typesystem.references.OwnedConverter.toLightweightReference(OwnedConverter.java:75)
    at org.eclipse.xtend.core.macro.declaration.CompilationUnitImpl$12.apply(CompilationUnitImpl.java:762)
    at org.eclipse.xtend.core.macro.declaration.CompilationUnitImpl$12.apply(CompilationUnitImpl.java:1)
    at org.eclipse.xtend.core.macro.declaration.CompilationUnitImpl.getOrCreate(CompilationUnitImpl.java:413)
    at org.eclipse.xtend.core.macro.declaration.CompilationUnitImpl.toTypeReference(CompilationUnitImpl.java:767)
    at org.eclipse.xtend.core.macro.declaration.JvmMethodDeclarationImpl.getReturnType(JvmMethodDeclarationImpl.java:79)
    at org.sculptor.generator.chain.ChainOverrideHelper$7.apply(ChainOverrideHelper.java:242)
    at org.sculptor.generator.chain.ChainOverrideHelper$7.apply(ChainOverrideHelper.java:240)

@tjuerge tjuerge assigned tjuerge and unassigned tavoda Feb 22, 2014
@tjuerge tjuerge added this to the 3.0.2 milestone Feb 22, 2014
@tjuerge
Copy link
Member

tjuerge commented Feb 22, 2014

With Xtext / Xtend 2.5.2 this seems to work now. I need this for #99.

tjuerge added a commit that referenced this issue Feb 22, 2014
…turn types and makes a few methods public (needed for #99)
tjuerge added a commit that referenced this issue Feb 23, 2014
…reate factory methods and re-adds the removed private keyword
@tjuerge tjuerge removed this from the 3.0.2 milestone Feb 23, 2014
@tjuerge
Copy link
Member

tjuerge commented Feb 23, 2014

Enabling @ChainOverridable for DslTransformation and using an extension for DslTransformation ends up in failing transformation tests:

Results :

Failed tests:
  DslTransformationTest.testTransformDslModel:100 Expected: [module1Name, module2Name], Actual: [module1Name, module2Name, module1Name, module2Name]
  DtoTransformationTest.assertModules:106 Expected: [media], Actual: [media, media]
  LibraryTransformationTest.assertModules:141 Expected: [media, person], Actual: [media, person, person, media]
  LibraryTransformationTest.assertPhysicalMediaRepository:451 null
  LibraryTransformationTest.assertMediaModule:151 Expected: [LibraryService, MediaService, MediaCharacterService, PhysicalMediaService], Actual: [LibraryService, MediaService, MediaCharacterService]
  RestTransformationTest.assertModules:137 Expected: [rest, person], Actual: [rest, person, rest, person]
  RestTransformationTest.assertRestModule:146 Expected: [CustomerService], Actual: []
  RestTransformationTest.assertCustomerScaffold:298 Expected: [createForm, create, show, showAll, delete], Actual: []
  UniverseTransformationTest.assertModules:111 Expected: [milkyway], Actual: [milkyway, milkyway]

Tests run: 74, Failures: 9, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] Sculptor :: Generator :: Core ..................... SUCCESS [29.308s]
[INFO] Sculptor :: Generator :: Test support ............. SUCCESS [2.089s]
[INFO] Sculptor :: Generator :: Core tests ............... FAILURE [39.744s]

With the test case DslTransformationTest.testTransformDslModel() in the feature branch feature/transformation-override this issue (here the same module is created multiple times) can be tested in isolation.

@tjuerge tjuerge reopened this Feb 23, 2014
@tjuerge tjuerge removed their assignment Mar 11, 2014
@tjuerge tjuerge added this to the 3.0.4 milestone Apr 26, 2014
@tjuerge tjuerge added 3 - Done and removed 1 - Ready labels May 4, 2014
@tjuerge tjuerge reopened this Mar 3, 2015
@tjuerge tjuerge added 1 - Ready and removed 3 - Done labels Mar 3, 2015
@tjuerge
Copy link
Member

tjuerge commented Mar 3, 2015

Using @ChainOverridable on Xtend classes which are maintaining state (explicitly via member variables or implicitly via the create methods cache implementation) leads to strange errors like this.

This is due to the inheritance hierarchy created by Sculptors active annotation processor and maintaining separate instances: The instance of the overriding class has it's state (via extending the class annotated with @ChainOverridable) and the instance of the overridable class has it's state. Calling methods on the overriding class or the overridable class manipulates the state within separate instances of the annotated class. With create methods this leads to creation of multiple instances due to separate caches implemented as private members named _createCache_<method name>_<counter>.

@tjuerge tjuerge modified the milestones: 3.0.4, 3.1.0 Mar 4, 2015
@tavoda
Copy link
Member

tavoda commented Mar 4, 2015

After all this troubles it is maybe time to change implementation. Maybe get rid of annotation processor (or at least extensive manipulation we use) and use some kind of proxy and IoC manipulations. What do you think?

@tavoda
Copy link
Member

tavoda commented Mar 18, 2015

Somebody took over our bug in Xtend:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=446364

Fix:
eclipse/xtext#43

Maybe we will be able to override also 'create' methods finally.

@tjuerge
Copy link
Member

tjuerge commented Mar 18, 2015

But this doesn't solve our issues with the cache implementation generated for Xtends create methods (as mentioned by Jan Koehnlein in his comment):
Every extension class gets its own instances of these caches. There's no global cache maintained across the chained extensions and the corresponding overriden template.

So it seems that we have to come up with our own cache implementation for create methods, eg. within the chain link code.

@tavoda
Copy link
Member

tavoda commented Mar 19, 2015

Yes I was playing with this, however I always found obstacle to finish it. That's why I filled this ticket on Xtend, 3 different errors always fired. Now 'maybe' we can find way to override create methods. It was impossible without this fix.

@tjuerge tjuerge removed this from the 3.1.0 milestone Apr 4, 2015
tjuerge added a commit that referenced this issue Apr 4, 2015
…methods by refactoring the overridable methods into a helper class
tjuerge added a commit that referenced this issue Apr 5, 2015
@tjuerge tjuerge removed the 1 - Ready label Jan 9, 2016
@tjuerge tjuerge assigned tavoda and unassigned rcodesmith Jan 24, 2020
tjuerge added a commit that referenced this issue Jan 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants