redhat-developer / vscode-java

Java Language Support for Visual Studio Code
Eclipse Public License 2.0
2.08k stars 441 forks source link

“Failed to configure project” when resources nested inside source folder #1590

Open pcantrell opened 4 years ago

pcantrell commented 4 years ago

The VS Code Java plugin cannot import a project from a build.gradle file that places a test resources directory inside a test source directory. Gradle itself, however, supports this.

Environment
Steps To Reproduce

Populate build.gradle with the following simple configuration:

plugins {
    id 'java'
}

sourceSets {
    test.java.srcDirs = ['test']
    test.resources.srcDirs = ['test/res']
}
Current Result

The VS Code plugin will produce a Failed to configure project error (with no further information, AFAICT).

However, gradle test will execute perfectly happily.

Expected Result

It should import the project with test/res copied to the test resources folder, just as gradle itself does.

testforstephen commented 4 years ago

Could you share the logs?

F1 -> Java: Open Java language server log file

pcantrell commented 4 years ago

Ah! I was sure there must be a stack trace somewhere, but couldn't find it. (Seems like it would be helpful if a click on the error message opened the log.) Here's the relevant section:

!ENTRY org.eclipse.buildship.core 4 0 2020-08-23 20:40:16.520
!MESSAGE Failed to configure project foo
!STACK 1
Java Model Exception: Java Model Status [Cannot nest 'foo/test/res' inside 'foo/test'. To enable the nesting exclude 'res/' from 'foo/test']
    at org.eclipse.jdt.internal.core.JavaModelOperation.runOperation(JavaModelOperation.java:798)
    at org.eclipse.jdt.internal.core.JavaProject.setRawClasspath(JavaProject.java:3608)
    at org.eclipse.jdt.internal.core.JavaProject.setRawClasspath(JavaProject.java:3568)
    at org.eclipse.jdt.internal.core.JavaProject.setRawClasspath(JavaProject.java:3624)
    at org.eclipse.buildship.core.internal.workspace.SourceFolderUpdater.updateSourceFolders(SourceFolderUpdater.java:71)
    at org.eclipse.buildship.core.internal.workspace.SourceFolderUpdater.update(SourceFolderUpdater.java:169)
    at org.eclipse.buildship.core.internal.workspace.BaseConfigurator.synchronizeJavaProjectInTransaction(BaseConfigurator.java:116)
    at org.eclipse.buildship.core.internal.workspace.BaseConfigurator.access$000(BaseConfigurator.java:40)
    at org.eclipse.buildship.core.internal.workspace.BaseConfigurator$1.run(BaseConfigurator.java:105)
    at org.eclipse.jdt.internal.core.BatchOperation.executeOperation(BatchOperation.java:41)
    at org.eclipse.jdt.internal.core.JavaModelOperation.run(JavaModelOperation.java:736)
    at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2292)
    at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2317)
    at org.eclipse.jdt.core.JavaCore.run(JavaCore.java:5895)
    at org.eclipse.jdt.core.JavaCore.run(JavaCore.java:5852)
    at org.eclipse.buildship.core.internal.workspace.BaseConfigurator.synchronizeJavaProject(BaseConfigurator.java:101)
    at org.eclipse.buildship.core.internal.workspace.BaseConfigurator.configure(BaseConfigurator.java:91)
    at org.eclipse.buildship.core.internal.workspace.BaseConfigurator.configure(BaseConfigurator.java:66)
    at org.eclipse.buildship.core.internal.extension.InternalProjectConfigurator.configure(InternalProjectConfigurator.java:65)
    at org.eclipse.buildship.core.internal.workspace.ProjectConfigurators.configureConfigurators(ProjectConfigurators.java:70)
    at org.eclipse.buildship.core.internal.workspace.SynchronizeGradleBuildOperation.synchronizeOpenWorkspaceProject(SynchronizeGradleBuildOperation.java:163)
    at org.eclipse.buildship.core.internal.workspace.SynchronizeGradleBuildOperation.synchronizeWorkspaceProject(SynchronizeGradleBuildOperation.java:137)
    at org.eclipse.buildship.core.internal.workspace.SynchronizeGradleBuildOperation.synchronizeGradleProjectWithWorkspaceProject(SynchronizeGradleBuildOperation.java:127)
    at org.eclipse.buildship.core.internal.workspace.SynchronizeGradleBuildOperation.access$000(SynchronizeGradleBuildOperation.java:42)
    at org.eclipse.buildship.core.internal.workspace.SynchronizeGradleBuildOperation$1.run(SynchronizeGradleBuildOperation.java:85)
    at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2292)
    at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2312)
    at org.eclipse.buildship.core.internal.workspace.SynchronizeGradleBuildOperation.synchronizeProjectsWithWorkspace(SynchronizeGradleBuildOperation.java:82)
    at org.eclipse.buildship.core.internal.workspace.SynchronizeGradleBuildOperation.run(SynchronizeGradleBuildOperation.java:64)
    at org.eclipse.buildship.core.internal.DefaultGradleBuild$SynchronizeOperation.runInToolingApi(DefaultGradleBuild.java:230)
    at org.eclipse.buildship.core.internal.operation.DefaultToolingApiOperationManager$WorkspaceRunnableAdapter.run(DefaultToolingApiOperationManager.java:58)
    at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2292)
    at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2317)
    at org.eclipse.buildship.core.internal.operation.DefaultToolingApiOperationManager.run(DefaultToolingApiOperationManager.java:39)
    at org.eclipse.buildship.core.internal.DefaultGradleBuild$SynchronizeOperation.run(DefaultGradleBuild.java:192)
    at org.eclipse.buildship.core.internal.DefaultGradleBuild.synchronize(DefaultGradleBuild.java:100)
    at org.eclipse.buildship.core.internal.DefaultGradleBuild.synchronize(DefaultGradleBuild.java:86)
    at org.eclipse.jdt.ls.core.internal.managers.GradleBuildSupport.update(GradleBuildSupport.java:83)
    at org.eclipse.jdt.ls.core.internal.managers.ProjectsManager$3.runInWorkspace(ProjectsManager.java:374)
    at org.eclipse.core.internal.resources.InternalWorkspaceJob.run(InternalWorkspaceJob.java:42)
    at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
!SUBENTRY 1 org.eclipse.jdt.core 4 964 2020-08-23 20:40:16.520
!MESSAGE Cannot nest 'foo/test/res' inside 'foo/test'. To enable the nesting exclude 'res/' from 'foo/test'

So it looks like the problem is that the eclipse build system is more strict than gradle.

testforstephen commented 4 years ago

You need manually exclude the nested folder. Could you try below?

plugins {
    id 'java'
}

sourceSets {
    main {
        java {
            srcDirs = ['test']
            exclude "res/**"
        }
        resources {
            srcDirs = ['test/res']
        }
    }
}
pcantrell commented 4 years ago

Thanks for the suggestion! I did find another workaround for my project; the point of this issue is just the discrepancy between gradle and VS Code behavior.

testforstephen commented 4 years ago

Could you share your workaround here in case some others may reference it for the similar issue?

pcantrell commented 4 years ago

Sure! It turns out things work fine if the test source dir is a resource dir (instead of containing a resource dir):

sourceSets {
    test.java.srcDirs = ['test']
    test.resources.srcDirs = ['test']
}

I had the luxury of moving files around, so this was an acceptable workaround in my case.

jheinem1 commented 1 year ago

This is still an issue for me, and unfortunately I don't have the luxury of moving my resource directory. My workaround was (as testforstephen suggested), modify my build.gradle to exclude the resources directory from my source directory, e.g.

sourceSets {
    main {
        java {
            srcDirs = ['src']
            exclude 'main/resources/**'
        }
        resources {
            srcDirs = ['src/main/resources']
        }
    }
}

which works, but I do have to ignore changes to build.gradle in git, which is somewhat of an annoyance.

(you can ignore file changes locally in git with git update-index --no-assume-unchanged [file])