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

"Model not available" error on non-Gradle project #984

Closed
mauromol opened this issue Apr 15, 2020 · 15 comments · Fixed by #1065
Closed

"Model not available" error on non-Gradle project #984

mauromol opened this issue Apr 15, 2020 · 15 comments · Fixed by #1065
Assignees
Milestone

Comments

@mauromol
Copy link

mauromol commented Apr 15, 2020

Expected Behavior

No error at all. I would even expect Buildship to do nothing on a non-Gradle project.

Current Behavior

Recently I started to get an error when building some Groovy projects (through "clean project" or through a change in a Groovy source file). These projects are NOT Gradle projects.
This is a screenshot:
immagine

And this is the contents of the Eclipse error log:

eclipse.buildId=4.14.0.I20191210-0610
java.version=1.8.0_242
java.vendor=Private Build
BootLoader constants: OS=linux, ARCH=x86_64, WS=gtk, NL=it_IT
Command-line arguments:  -data file:/home/mauro/workspace/rolling/DCS-SHOP-trunk/ -os linux -ws gtk -arch x86_64

org.eclipse.core.resources
Error
Wed Apr 15 09:56:40 CEST 2020
Problems occurred when invoking code from plug-in: "org.eclipse.core.resources".

java.lang.RuntimeException: Failed to bootstrap GroovyClassLoaders for project 'TestGroovy'
	at org.codehaus.jdt.groovy.internal.compiler.GroovyClassLoaderFactory.getProjectGroovyClassLoaders(GroovyClassLoaderFactory.java:174)
	at org.codehaus.jdt.groovy.internal.compiler.GroovyClassLoaderFactory.getGroovyClassLoaders(GroovyClassLoaderFactory.java:115)
	at org.codehaus.jdt.groovy.internal.compiler.ast.GroovyParser.lambda$0(GroovyParser.java:120)
	at org.codehaus.jdt.groovy.internal.compiler.ast.GroovyParser.dietParse(GroovyParser.java:181)
	at org.codehaus.jdt.groovy.integration.internal.MultiplexingParser.dietParse(MultiplexingParser.java:45)
	at org.eclipse.jdt.internal.compiler.Compiler.internalBeginToCompile(Compiler.java:861)
	at org.eclipse.jdt.internal.compiler.Compiler.beginToCompile(Compiler.java:404)
	at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:454)
	at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:436)
	at org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:410)
	at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.compile(BatchImageBuilder.java:218)
	at org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:342)
	at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.build(BatchImageBuilder.java:80)
	at org.eclipse.jdt.internal.core.builder.JavaBuilder.buildAll(JavaBuilder.java:275)
	at org.eclipse.jdt.internal.core.builder.JavaBuilder.build(JavaBuilder.java:187)
	at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:833)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:220)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:263)
	at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:316)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:319)
	at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:371)
	at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:392)
	at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:154)
	at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:244)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
	at org.codehaus.jdt.groovy.internal.compiler.GroovyClassLoaderFactory.calculateClasspath(GroovyClassLoaderFactory.java:198)
	at org.codehaus.jdt.groovy.internal.compiler.GroovyClassLoaderFactory.lambda$2(GroovyClassLoaderFactory.java:151)
	at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
	at org.codehaus.jdt.groovy.internal.compiler.GroovyClassLoaderFactory.getProjectGroovyClassLoaders(GroovyClassLoaderFactory.java:149)
	... 26 more
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.GeneratedMethodAccessor47.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.eclipse.jdt.groovy.core.util.ReflectionUtils.throwableExecutePrivateMethod(ReflectionUtils.java:117)
	at org.codehaus.jdt.groovy.internal.compiler.GroovyClassLoaderFactory.resolveRuntimeClasspathEntry(GroovyClassLoaderFactory.java:204)
	at org.codehaus.jdt.groovy.internal.compiler.GroovyClassLoaderFactory.calculateClasspath(GroovyClassLoaderFactory.java:191)
	... 29 more
Caused by: org.eclipse.buildship.core.internal.GradlePluginsRuntimeException: Model not available for TestGroovy
	at org.eclipse.buildship.core.internal.workspace.GradleClasspathContainerRuntimeClasspathEntryResolver.resolveRuntimeClasspathEntry(GradleClasspathContainerRuntimeClasspathEntryResolver.java:77)
	at org.eclipse.buildship.core.internal.workspace.GradleClasspathContainerRuntimeClasspathEntryResolver.resolveRuntimeClasspathEntry(GradleClasspathContainerRuntimeClasspathEntryResolver.java:66)
	at org.eclipse.jdt.internal.launching.RuntimeClasspathEntryResolver.resolveRuntimeClasspathEntry(RuntimeClasspathEntryResolver.java:110)
	at org.eclipse.jdt.launching.JavaRuntime.resolveRuntimeClasspathEntry(JavaRuntime.java:1505)
	at org.eclipse.jdt.internal.launching.DefaultEntryResolver.resolveRuntimeClasspathEntry(DefaultEntryResolver.java:70)
	at org.eclipse.jdt.launching.JavaRuntime.resolveRuntimeClasspathEntry(JavaRuntime.java:1508)
	at org.eclipse.jdt.launching.JavaRuntime.resolveRuntimeClasspathEntry(JavaRuntime.java:1444)
	... 35 more

The mentioned TestGroovy project is an Eclipse Groovy project with neither a Gradle nature nor a build.gradle script.

This error was also reported to the Groovy Eclipse plugin issue tracker: groovy/groovy-eclipse#1087

Context

Just trying to perform an incremental or full build of a plain Eclipse Groovy project (not being a Gradle project).
Started to happen recently, although I can't say when. Perhaps from when I upgraded to Eclipse 2019-12, but I don't know for sure.

Current Buildship version is 3.1.3.v20191118-1057.

Steps to Reproduce

Create a simple Groovy project (not a Gradle project).
Restart your IDE.
Do Project | Clean... to clean that project.

I don't know if this can be reproduced consistently just after the first restart after creating the Groovy project. I'm pretty sure that upon creation, no error is given until you restart, because I know for sure that I used this TestGroovy project for a while, with no problems. Currently, I can reproduce this problem always, whenever I try yo clean this project or to save a change in any of the Groovy source files in it.
I was not able to find a way to fix this problem. I usually have to delete the affected project and re-create from scratch. Fortunately for me, this is happening on test projects.

Your Environment

This happens on both a Windows and a Linux systems. They both use the same Eclipse, Groovy Eclipse plugin and Buildship versions.

@mauromol mauromol changed the title "Model not available" error non non-Gradle project "Model not available" error on non-Gradle project Apr 15, 2020
@mauromol
Copy link
Author

During the analysis for groovy/groovy-eclipse#1087, it turns out that the problem is likely to be determined by the fact that my Groovy non-Gradle project depends on a Gradle project. It seems like an attempt to resolve transitive dependencies from the Groovy Plugin triggers an attempt from Buildship to resolve even the dependent project as a Gradle project, and this fails because it is not, indeed.
An attempt was made to change how this resolution is performed on Groovy Plugin side, but still unsuccessfully.
Maybe you have some insight of what is going on?
I have been working with such a project setup for years with no problems, only recently I started to see this exception.
I know it's an unusual setup, but it is something I commonly use to write some quick Groovy test code (using the Groovy console) for classes that are hosted in a Gradle project.

@donat
Copy link
Contributor

donat commented Jan 29, 2021

Sorry for the late reply.

Given the complexity, it would take a a considerable effort just to reproduce the problem on my side. Could you prepare a minimal example workspace exhibiting the problem? I'd be happy to take a look.

@donat donat assigned donat and unassigned donat Jan 29, 2021
@mauromol
Copy link
Author

Hi Donat,
@eric-milles identified this as a JDT bug and opened: https://bugs.eclipse.org/bugs/show_bug.cgi?id=562224
He also submitted a Gerrit change, which however remained somewhat hanging. Maybe you can help to push it forward?

Let me know if you still need me to prepare a test case.

@eric-milles
Copy link

eric-milles commented Jan 29, 2021

Here is the example structure:

  /JavaProject
    typical JRE, source and output classpath entries, plus:
    <classpathentry kind="src" path="/GradleProject" combineaccessrules="false"/>
  /GradleProject
    typical JRE, source and output classpath entries, plus:
    <classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>

When calling API JavaRuntime.resolveRuntimeClasspathEntry(IRuntimeClasspathEntry,IJavaProject) to get the resolved runtime classpath of JavaProject, the Gradle container fails with exception: org.eclipse.buildship.core.internal.GradlePluginsRuntimeException: Model not available for JavaProject

As stated, there are more details in the eclipse bug. I believe this could be fixed on your side as well. When resolving a classpath entry, there is the passed java project reference as well as a reference available through an accessor. Whichever is used, if the other were used instead, the NPE could be avoided. I don't know if the semantics of the two references are different, but one is not always available.

Groovy Development Tools makes the JavaRuntime.resolveRuntimeClasspathEntry call, so you could add that to your test fixture if you don't want to figure how to drive the eclipse method call.

@donat
Copy link
Contributor

donat commented Feb 24, 2021

When calling API JavaRuntime.resolveRuntimeClasspathEntry(IRuntimeClasspathEntry,IJavaProject) to get the resolved runtime classpath of JavaProject, the Gradle container fails with exception: org.eclipse.buildship.core.internal.GradlePluginsRuntimeException: Model not available for JavaProject

The exception happens only if the referenced Gradle project hasn't been synced and the classpath

I think I understand the situation a bit better. The use-case happens when the referenced Gradle project has not been synced and consequently the classpath container data is still uninitialized.

For the context of Buildship, this is correct. All Gradle projects are added to the workspace via synchronization, therefore the classpath container data is always present.

I see two paths to solve the situation in Buildship:

  • Ignore the missing data and return an empty result when resolving the classpath container
  • Run asynchronous sync and return the correct result.

I'm leaning towards the first approach as it would give back the same state to /JavaProject what's currently defined on /GradleProject. Does it make sense to you @eric-milles?

@mauromol
Copy link
Author

The exception happens only if the referenced Gradle project hasn't been synced and the classpath

I think I understand the situation a bit better. The use-case happens when the referenced Gradle project has not been synced and consequently the classpath container data is still uninitialized.

Not sure if I understand this correctly. But I can reproduce this problem consistently, on each save of a Groovy file in the dependent project, independently on whether the classpath container "Project and external dependencies" in the dependency project is populated or not. Gradle => Refresh Gradle Project on the dependency project does not help.

Indeed this setup currently never works at all.

@donat
Copy link
Contributor

donat commented Feb 24, 2021

OK, that is really weird. The class responsible for loading/saving model data is simple: https://github.com/eclipse/buildship/blob/321da3ad3e351f8c9ba7300a142f978fd2851081/org.eclipse.buildship.core/src/main/java/org/eclipse/buildship/core/internal/preferences/DefaultModelPersistence.java
Maybe the code is not thread-safe and the sync/load is executed on different threds?
Or, it's more likely that using IProject references for the cache key is incorrect. I can imagine that the Groovy plugin uses a different IProject instance to represent the same project.

@mauromol
Copy link
Author

Hi Donat, reproducing is really easy. I prepared a workspace for you:
TestGradleIssue984.zip

This was produced by simply doing:

  • New | Gradle Project... and created GradleProject
  • New | Groovy Project... and created GroovyProject
  • then, in the GroovyProject properties I added GradleProject to the classpath
  • then I added a Groovy class (test.Test) in GroovyProject
  • try to make any change to test.Test and save: you'll see the exception

In order to try this:

  • ensure your Eclipse installation has Groovy Eclipse Plugin installed: if needed, install it from an update site (https://github.com/groovy/groovy-eclipse/wiki#releases) or from the marketplace
  • unzip the attached file anywhere: it contains the whole workspace I created with Eclipse 2020-09, Buildship 3.1.5.v20210113-0929, Groovy Eclipse Plugin 4.1.0.v202101182113-e2009
  • open Eclipse on the unzipped workspace

@donat
Copy link
Contributor

donat commented Feb 26, 2021

Thanks for the sample project. Now I think I understand the problem. The runtime classpath entry resolver points to a wrong project when the resoultion starts from an external project. I'll create a snapshot release for you to evaluate.

@donat
Copy link
Contributor

donat commented Mar 1, 2021

@mauromol
Copy link
Author

mauromol commented Mar 1, 2021

@donat I made a quick test and I don't get the exception any more! So it seems like it's working fine now. Thank you!

@donat
Copy link
Contributor

donat commented Mar 2, 2021

Thanks for the confirmation!

@donat
Copy link
Contributor

donat commented Mar 3, 2021

The fix is now merged and part of the latest snapshot release.

@ishridharhegde
Copy link

ishridharhegde commented Apr 18, 2023

Facing this issue for normal Java project on the following version:

Version: 2023-03 (4.27.0)
Build id: 20230309-1520

Edit: The problem got solved after I removed the buildship Gradle classpath entry from the .classpathfile

@loicdesguin
Copy link

Hello,

Looks like I have the same issue :

is causing an error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants