Eclipse API:如何为IJavaProject创建批量更改资源

时间:2014-03-20 19:15:59

标签: java eclipse eclipse-plugin

(注意:解决方案如下)

我正在尝试在批量处理资源更改事件时创建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;
}

1 个答案:

答案 0 :(得分:1)

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