(注意:解决方案如下)

我正在尝试在批量处理资源更改事件时创建一个IJavaProject,但是却遇到以下异常:

Java Model Exception: Java Model Status [Cannot nest 'JavaProject/src' inside 'JavaProject'. To enable the nesting exclude 'src/' from 'JavaProject']

我在第二次设置原始类路径的行上抛出了异常(在下面的代码中,在结尾处有注释)。

没有批处理(即:删除IWorkspaceRunnable和相关代码),我的IJavaProject初始化就很好。那么,如何创建具有批处理资源更改事件的IJavaProject?

这是我的代码,而我创建IJavaProject的方法主要来自here

public static IJavaProject getJavaProjectBatched(final IProject project,
                                                 final String sourceFolderPath,
                                                 final String binFolderPath)
    throws CoreException
{
    IWorkspaceRunnable r = new IWorkspaceRunnable()
    {
        @Override
        public void run(@Nullable IProgressMonitor monitor) throws CoreException
        {
            if (!project.exists())
                ResourceUtility.createProject(project);

            IProjectDescription description = project.getDescription();
            description.setNatureIds(new String[] {JavaCore.NATURE_ID});
            project.setDescription(description, null);

            IFolder binFolder = project.getFolder(binFolderPath);
            binFolder.create(false, true, null);

            final IFolder sourceFolder = project.getFolder(sourceFolderPath);
            sourceFolder.create(false, true, null);

            final IJavaProject javaProject = JavaCore.create(project);
            javaProject.setOutputLocation(binFolder.getFullPath(), null);

            List<IClasspathEntry> entries = new ArrayList<>();
            IVMInstall vmInstall = JavaRuntime.getDefaultVMInstall();
            LibraryLocation[] locations = JavaRuntime.getLibraryLocations(vmInstall);
            for (LibraryLocation element: locations)
            {
                entries.add(JavaCore.newLibraryEntry(element.getSystemLibraryPath(), null, null));
            }
            IPackageFragmentRoot root = javaProject.getPackageFragmentRoot(sourceFolder);
            IClasspathEntry[] oldEntries = javaProject.getRawClasspath();
            IClasspathEntry[] newEntries = new IClasspathEntry[oldEntries.length + 1];
            System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length);
            newEntries[oldEntries.length] = JavaCore.newSourceEntry(root.getPath());
            // add libs to project class path
            javaProject.setRawClasspath(entries.toArray(new IClasspathEntry[entries.size()]),
                                        null);
            javaProject.setRawClasspath(newEntries, null);// Exception is thrown HERE!!!
        }
    };

    project.getWorkspace().run(r, null, IWorkspace.AVOID_UPDATE, null);
    @SuppressWarnings("null") @NonNull IJavaProject jp = JavaCore.create(project);
    return jp;
}


最终解决方案

在下面的答案中,在nitind的帮助下,我制定了适合自己需要的批处理版本。简而言之-这是如何创建一个模仿Eclipse内部资源树表示形式的IJavaProject。

这是我更广泛的问题的一部分,发布了here谢谢您的帮助。

public static IJavaProject getJavaProjectBatched(final IProject project, final String sourceFolderPath,
                                                 final String binFolderPath) throws CoreException
{
    IWorkspaceRunnable r = new IWorkspaceRunnable()
    {
         @Override public void run(@Nullable IProgressMonitor monitor) throws CoreException
        {
             if (!project.exists())
                 ResourceUtility.createProject(project);

             IProjectDescription description = project.getDescription();
             description.setNatureIds(new String[] {JavaCore.NATURE_ID});
             project.setDescription(description, null);

             IFolder binFolder = project.getFolder(binFolderPath);
             binFolder.create(false, true, null);
             final IFolder sourceFolder = project.getFolder(sourceFolderPath);
             sourceFolder.create(false, true, null);

             final IJavaProject javaProject = JavaCore.create(project);
             javaProject.setOutputLocation(binFolder.getFullPath(), null);

            IPackageFragmentRoot root = javaProject.getPackageFragmentRoot(sourceFolder);
            IClasspathEntry[] newEntries = new IClasspathEntry[1];
            newEntries[0] = JavaCore.newSourceEntry(root.getPath());
            javaProject.setRawClasspath(newEntries, null);
        }
    };

    project.getWorkspace().run(r, null,IWorkspace.AVOID_UPDATE, null);
    @SuppressWarnings("null") @NonNull IJavaProject javaProject = JavaCore.create(project);
    return javaProject;
}

最佳答案

它告诉您,除非在表示整个项目的条目中排除该文件夹,否则您不能在Java Build Path上拥有该项目本身及其文件夹之一。由于您正在创建项目,因此请跳过oldEntries。

09-08 07:40