NetBeans平台重新打开已关闭的项目StackOverflowError

时间:2015-06-25 07:12:51

标签: netbeans-platform project-types

我正在编写基于NetBeans平台(7.4)的应用程序,我创建了一个自定义的ProjecType和FileType。 ProjectType具有弱文件更改侦听器,用于在项目文件夹中删除新文件。问题是如果我打开一个项目,关闭它然后再次尝试重新打开它,它会耗尽内存并抛出一个Mutex异常:

  

Blockquote java.lang.IllegalStateException:在保存ProjectManager.mutex时不应获取Children.MUTEX

或IllegalStateException:

  

Blockquote java.lang.IllegalStateException:at org.openide.nodes.Node.assignTo(Node.java:354)      在org.openide.nodes.EntrySupportDefault.justComputeNodes(EntrySupportDefault.java:212)      在org.openide.nodes.ChildrenArray.nodes(ChildrenArray.java:88)      在org.openide.nodes.EntrySupportDefault.getNodes(EntrySupportDefault.java:130)      在org.openide.nodes.EntrySupportDefault.getNodes(EntrySupportDefault.java:172)      在org.openide.nodes.Children.getNodes(Children.java:469)

另一个有趣的事情是,如果我关闭项目并对项目文件夹进行任何小的更改,例如将其移动到新位置,或者甚至只是在该文件夹中打开文件,当我尝试重新加载它时它工作正常。 我试过完全删除弱文件监听器但没有成功。我知道这不是文件更改侦听器问题,因为Windows不会阻止我操纵项目文件夹中的文件。 Bellow是我的ProjectNodeFactory,它为项目文件夹中每个识别的文件类型创建子节点。

public class MyProjectNodeFactory extends ChildFactory<FileObject> implements FileChangeListener {

private final FileObject projectFolder;

public MyProjectNodeFactory(MyProjectNode project) {
    this.projectFolder = project.getProjectDirectory();                 
    project.addFileChangeListener(this);
    refresh(true);
}

@Override
protected boolean createKeys(List<FileObject> list) {

    for (FileObject fileObject : Collections.list(projectFolder.getData(false)))
    {
        if (fileObject.getExt().equals(Bundle.MY_FILETYPE_EXTENSION())) {
            list.add(fileObject);
        }
    }
    return true;
}

@Override
protected Node[] createNodesForKey(FileObject key) {
    ArrayList<Node> nodes = new ArrayList<Node>();
    // Add data files                            
    try {
        if(key.getExt().equals(Bundle.MY_FYLETYPE_EXTENSION()))
        {   
            nodes.add(DataObject.find(key).getNodeDelegate());                
        }
    } catch (DataObjectNotFoundException ex) {
        Exceptions.printStackTrace(ex);                
    }                            
    return (nodes.toArray(new Node[nodes.size()]));
}

另外我的ProjecType LogicalView和ProjectNode

public class MyProjectType implements Project {

private final FileObject projectDir;
private final ProjectState state;
private FileChangeListener fileChangeListener;
private Lookup lkp;

MyProjectType(FileObject dir, ProjectState state) {
    this.projectDir = dir;
    this.state = state;
}

@Override
public FileObject getProjectDirectory() {
    return projectDir;
}

@Override
public Lookup getLookup() {
    if (lkp == null) {
        lkp = Lookups.fixed(new Object[]{
            // register your features here
            this,
            new MyProjectInfo(),
            new MyProjectLogicalView(this),});
    }
    return lkp;
}

public void addFileChangeListener(FileChangeListener regularFileChangeListener) {
    this.fileChangeListener = (FileChangeListener)WeakListeners.create(FileChangeListener.class, regularFileChangeListener, this.projectDir.getPath());        
    this.projectDir.addFileChangeListener(fileChangeListener);
}

public void removeFileChangeListeners() {
    if(fileChangeListener!=null)
        this.projectDir.removeFileChangeListener(fileChangeListener);
}

private final class MyProjectInfo implements ProjectInformation {

    @StaticResource()
    public static final String PROJECT_ICON = "projectIcon.png";

   ..................

}

class MyProjectLogicalView implements LogicalViewProvider {

    @StaticResource()
    public static final String PROJECT_ICON = "projectIcon.png";

    private final MyProjectType project;

    public MyProjectLogicalView(MyProjectType project) {
        this.project = project;       
    }

    @Override
    public Node createLogicalView() {
        try {
            FileObject projectDirectory = project.getProjectDirectory();
            DataFolder projectFolder = DataFolder.findFolder(projectDirectory);
            Node nodeOfProjectFolder = projectFolder.getNodeDelegate();

            return new ProjectNode(nodeOfProjectFolder, project);
        } catch (DataObjectNotFoundException donfe) {
            Exceptions.printStackTrace(donfe);
            return new AbstractNode(Children.LEAF);
        }
    }

    private final class ProjectNode extends FilterNode {

        final MyProjectType project;

        public ProjectNode(Node node, MyProjectType project)
                throws DataObjectNotFoundException {
            super(node,
                    Children.create(new MyProjectNodeFactory(project),true),
                    new ProxyLookup(
                            new Lookup[]{
                                Lookups.singleton(project),
                                node.getLookup()
                            }));
            this.project = project;
        }

        @Override
        public Action[] getActions(boolean arg0) {
            return new Action[]{
                CommonProjectActions.newFileAction(),
                CommonProjectActions.copyProjectAction(),
                CommonProjectActions.deleteProjectAction(),
                CommonProjectActions.closeProjectAction()
            };
        }

       ...............
    }

}

1 个答案:

答案 0 :(得分:1)

After a lot of googling and debugging I was not able to detect why this memory leak happens, but I did find a solution at the following link which might be useful to other people running into the same issue. Solution to Open/Close/Re-Open a NetBeans Platform ProjectType The solution is to get a clone of the child nodes instead of just the delegate. public Node node(FileObject key) { DataFolder folder = DataFolder.findFolder(key); return folder.getNodeDelegate().cloneNode(); } I still do not understand why the getNodeDelegate() is not sufficient, but I assume when the Project is first closed, some references are not released and it runs into issues when reopening. By getting the clone, it creates a whole new parent node without those issues. I hope this helps somebody because I had a hard time finding a solution to it.