sebastianbenz / Jnario

Executable specifications for Java
136 stars 38 forks source link

LinkageError during build #149

Closed apeteri closed 9 years ago

apeteri commented 9 years ago

Hi,

I get the following exception when Jnario's builder processes a source file:

Errors running builder 'Xtext Project Builder' on project 'project-name'.

java.lang.LinkageError: loader constraint violation: when resolving method "org.jnario.jvmmodel.ExtendedJvmTypesBuilder.toField(Lorg/eclipse/emf/ecore/EObject;Ljava/lang/String;Lorg/eclipse/xtext/common/types/JvmTypeReference;Lorg/eclipse/xtext/xbase/lib/Procedures$Procedure1;)Lorg/eclipse/xtext/common/types/JvmField;" 
the class loader (instance of org/eclipse/osgi/internal/loader/EquinoxClassLoader) of the current class, org/jnario/spec/jvmmodel/ImplicitSubject, 
and the class loader (instance of org/eclipse/osgi/internal/loader/EquinoxClassLoader) for resolved class, org/jnario/jvmmodel/ExtendedJvmTypesBuilder, 
have different Class objects for the type /emf/ecore/EObject;Ljava/lang/String;Lorg/eclipse/xtext/common/types/JvmTypeReference;Lorg/eclipse/xtext/xbase/lib/Procedures$Procedure1;)Lorg/eclipse/xtext/common/types/JvmField; used in the signature

at org.jnario.spec.jvmmodel.ImplicitSubject.addImplicitSubject(ImplicitSubject.java:87)
at org.jnario.spec.jvmmodel.SpecJvmModelInferrer.initialize(SpecJvmModelInferrer.java:219)
at org.jnario.spec.jvmmodel.SpecJvmModelInferrer$1.run(SpecJvmModelInferrer.java:151)
at org.jnario.spec.jvmmodel.SpecJvmModelInferrer.doInfer(SpecJvmModelInferrer.java:131)
at org.jnario.jvmmodel.JnarioJvmModelInferrer.infer(JnarioJvmModelInferrer.java:91)
at org.eclipse.xtext.xbase.jvmmodel.JvmModelAssociator.installDerivedState(JvmModelAssociator.java:303)
at org.eclipse.xtext.resource.DerivedStateAwareResource.installDerivedState(DerivedStateAwareResource.java:145)
at org.eclipse.xtext.xbase.resource.BatchLinkableResource.getContents(BatchLinkableResource.java:128)
at org.eclipse.xtext.xbase.typesystem.internal.LogicalContainerAwareBatchTypeResolver.getEntryPoints(LogicalContainerAwareBatchTypeResolver.java:27)
at org.eclipse.xtend.core.typesystem.TypeDeclarationAwareBatchTypeResolver.getEntryPoints(TypeDeclarationAwareBatchTypeResolver.java:27)
at org.eclipse.xtext.xbase.typesystem.internal.DefaultBatchTypeResolver.getTypeResolver(DefaultBatchTypeResolver.java:53)
at org.eclipse.xtext.xbase.typesystem.internal.CachingBatchTypeResolver$1.get(CachingBatchTypeResolver.java:47)
at org.eclipse.xtext.xbase.typesystem.internal.CachingBatchTypeResolver$1.get(CachingBatchTypeResolver.java:1)
at org.eclipse.xtext.util.OnChangeEvictingCache.get(OnChangeEvictingCache.java:75)
at org.eclipse.xtext.xbase.typesystem.internal.CachingBatchTypeResolver.doResolveTypes(CachingBatchTypeResolver.java:45)
at org.eclipse.xtext.xbase.typesystem.internal.AbstractBatchTypeResolver.resolveTypes(AbstractBatchTypeResolver.java:44)
at org.eclipse.xtext.xbase.resource.BatchLinkingService.resolveBatched(BatchLinkingService.java:45)
at org.eclipse.xtext.xbase.resource.BatchLinkableResource.resolveLazyCrossReferences(BatchLinkableResource.java:145)
at org.eclipse.xtext.EcoreUtil2.resolveLazyCrossReferences(EcoreUtil2.java:513)
at org.eclipse.xtext.builder.clustering.ClusteringBuilderState.doUpdate(ClusteringBuilderState.java:210)
at org.eclipse.xtext.builder.builderState.AbstractBuilderState.update(AbstractBuilderState.java:112)
at org.eclipse.xtext.builder.impl.XtextBuilder.doBuild(XtextBuilder.java:188)
at org.eclipse.xtext.builder.impl.XtextBuilder.fullBuild(XtextBuilder.java:214)
at org.eclipse.xtext.builder.impl.XtextBuilder.build(XtextBuilder.java:89)
at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:734)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:206)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:246)
at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:299)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:302)
at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:358)
at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:381)
at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:143)
at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:241)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)

When debugging a running instance, I set a breakpoint in ImplicitSubject and evaluated the last executed line, ImplicitSubject.java:87 of the stack trace, which resulted in the following exception:

com.sun.jdi.InvalidTypeException: Generated value (org.jnario.spec.jvmmodel.ImplicitSubject$1) is not compatible with declared type (org.eclipse.xtext.xbase.lib.Procedures$Procedure1). occurred invoking method.

Which also seem to indicate that somehow the anonymous class' parent Procedure1 ends up getting loaded by two different classloaders, but I couldn't figure out how and why.

Similar exceptions appear when the outline view and highlighting is updated in any spec or feature editor, but they usually involve org.jnario.jvmmodel.ExtendedJvmTypesBuilder.toMethod instead, with similar inner callback Procedure1 classes.

Using Luna SR1, Jnario 1.0.0.201407142310, Xtext and Xtend SDK 2.6.2.v201407030533.

sebastianbenz commented 9 years ago

Could you please provide an example project for me to reproduce the problem.

apeteri commented 9 years ago

Hello Sebastian,

The stack trace mentions SpecJvmModelInferrer, but minimal feature files also exhibited this behavior when I added a very simple scenario (I used the calculator example from the Jnario website, without an actual Calculator, just adding two ints together, and checking the result).

The issue first came up with an earlier Eclipse installation, where lots of additional Eclipse features were gathered over time. Since my initial report, I did some further debugging using that instance, which revealed that a third-party bundle wrapped a separate set of Xtend and Xbase libraries and exported them via an Export-Package directive -- so there actually were two different sources for Procedure1. Uninstalling the third-party bundle solved the problem.

The cause seems to be completely external to Jnario, so I'd opt for closing the issue.

sebastianbenz commented 9 years ago

That indeed explains your problems. Thanks for letting me know.

tkokasih commented 9 years ago

@apeteri : Is it possible to give details on how to identify the external bundle that use the Export-Package directive? I encounter the same issue but I cannot find which bundle to remove.

apeteri commented 9 years ago

Hi @tkokasih,

In my case, the issue originated from the Eclipse theme plugin (which I do like) by @jeeeyul. If you don't have it installed, and want to dive deep into troubleshooting, you'll have to check the class loader of the interface Procedure1 in a debugger at ImplicitSubject.java:87, while connecting to the problematic Eclipse instance using remote debug.

One reference to check is the (actual) parameter _function; you can evaluate the following expression in the Display view when the breakpoint is hit:

_function.getClass().getInterfaces()[0].getClassLoader() 

The other is the last (formal) parameter of ExtendedJvmTypesBuilder.toField(...); for that, you'll have to take a look at all methods of the class by inspecting the return value of the following expression:

ExtendedJvmTypesBuilder.class.getMethods() 

Find the appropriate array index "n" for the method toMethod(EObject, String, JvmTypeReference, Procedure1), then evaluate the following (in the example below, the index is 15):

ExtendedJvmTypesBuilder.class.getMethods()[15].getParameterTypes[3].getClassLoader()

...to display the class loader for the fourth argument.

The string output of bundle class loaders should reveal the bundle they represent. If the values do not differ, you'll also have to check the other arguments in a similar fashion to determine whether EObject or JvmTypeReference comes from different class loaders at the point where the exception is thrown.