Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Eclipse Plug In: IDE.openEditor throws IllegalArgumentException

I'm writing an Eclipse plugin. It runs a code analysis on Java code and, using a ListViewer, reports lines of code that violate certain criteria. When somebody selects one of those lines in the listviewer, I want to open the Eclipse Java file editor to that file and go to that line. The way the analysis works, each violation has a field holding the file that the violation occurs in as a standard java.io.File. So, I need to turn this into an IFile so I can open it in the Eclipse Java editor.

Here's most of the code that runs when the user clicks one of the lines in the listviewer. Violation is the class I made to represent a specific line of Java code that violates some criteria:

Violation selectedViolation = <I get this from the ListViewer> 
IPath path = new Path(violation.getSourceFile().getAbsolutePath());
IFile toOpen = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
IEditorPart editorPart =  PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
if (editorPart == null) {
    IWorkbenchPage curPage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
    editorPart = IDE.openEditor(curPage, toOpen, true);
}

Running this, I get IllegalArgumentException on the line that invokes IDE.openEditor (which corresponds to CalisthenicsView.java:75):

at org.eclipse.ui.part.FileEditorInput.getPath(FileEditorInput.java:218)
at org.eclipse.ui.internal.WorkbenchPage.busyOpenEditor(WorkbenchPage.java:3163)
at org.eclipse.ui.internal.WorkbenchPage.access$25(WorkbenchPage.java:3149)
at org.eclipse.ui.internal.WorkbenchPage$10.run(WorkbenchPage.java:3131)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
at org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPage.java:3126)
at org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPage.java:3090)
at org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPage.java:3080)
at org.eclipse.ui.ide.IDE.openEditor(IDE.java:541)
at org.eclipse.ui.ide.IDE.openEditor(IDE.java:500)
at com.chairbender.eclipse.object_calisthenics_analyzer.views.CalisthenicsView$1.selectionChanged(CalisthenicsView.java:75)

I've looked at the line of source code that throws this in FileEditorInput.java:218. Apparently it does this (where "file" is the same as "toOpen" in the first code block):

 final URI locationURI = file.getLocationURI();
 if (locationURI == null)
   throw new IllegalArgumentException();

To me, it seems like .getFile(path) is returning an IFile that doesn't have a locationURI, for some reason. I don't know why.

Is there a way to fix this? Is there a different way I can accomplish this (opening a Java editor to a specific line of a specific file)? Keep in mind that I don't have access to an IProject, since this analysis can be run on any project in the workspace or even the entire workspace.

EDIT: Another thing I don't understand is the code that's trying to invoke FileEditorInput.getPaht(). Looking at WorkbenchPage.busyOpenEditor on line 3163:

// Special handling for external editors (they have no tabs...)
    if ("org.eclipse.ui.systemExternalEditor".equals(editorId)) { //$NON-NLS-1$
        IPathEditorInput fileInput = getPathEditorInput(input);
        if (fileInput == null) {
            throw new PartInitException(WorkbenchMessages.EditorManager_systemEditorError);
        }

        String fullPath = fileInput.getPath().toOSString();
        Program.launch(fullPath);
        return null;
    }

This is the code that invokes FileEditorInput.getPath(). Apparently it is trying to open something called an "external editor", which sounds like it's not what I want it to do. I just want to open the default Java source code editor. This sounds like it's trying to open something else.

Also, I wanted to add that the .toString() value of toOpen (the IFile I'm trying to open) is: L/Programming/runtime-New_configuration/slackbot-resistance/src/main/java/com/chairbender/slackbot/resistance/ResistanceBot.java

...so it's definitely not null or invalid and I would assume Eclipse knows it's a Java file.

like image 830
chairbender Avatar asked May 14 '26 15:05

chairbender


1 Answers

IPath path = new Path(violation.getSourceFile().getAbsolutePath());
IFile toOpen = ResourcesPlugin.getWorkspace().getRoot().getFile(path);

You appear to be passing an absolute file path to the getFile method. The JavaDoc for this says:

This is a resource handle operation; neither the resource nor the result need exist in the workspace. The validation check on the resource name/path is not done when the resource handle is constructed; rather, it is done automatically as the resource is created.

The supplied path may be absolute or relative; in either case, it is interpreted as relative to this resource and is appended to this container's full path to form the full path of the resultant resource. A trailing separator is ignored. The path of the resulting resource must have at least two segments.

So the path is interpreted as relative to the current workspace (that is your test workspace not your development workspace). No test is done to see if the file actually exists.

The exception inside IDE.openEditor is because the IFile does not appear to be in a valid project in the workspace. This is also why it is trying to open an external editor.

If you want to open a file which is not in the workspace you need to use an IURIEditorInput as implemented by FileStoreEditorInput:

IFileStore store = EFS.getStore(file.toURI());

IEditorInput input = new FileStoreEditorInput(store);

IDE.openEditor(page, input, "editor id", true);

Note: Some editors don't support files which are not in the workspace, others may have reduced functionality.

The editor id for the Java editor is given by JavaUI.ID_CU_EDITOR ("org.eclipse.jdt.ui.CompilationUnitEditor")

If you have a file which is in the workspace but you only have the absolute path of the file use IWorkspaceRoot.getFileForLocation:

IFile toOpen = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);

Note: This will return null if the IFile cannot be found.

like image 150
greg-449 Avatar answered May 16 '26 03:05

greg-449



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!