Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 418584

Summary: Unable to load factory names from container [target\classes]
Product: [Eclipse Project] JDT Reporter: Matt Kusnierz <matthew.kusnierz>
Component: APTAssignee: Generic inbox for the JDT-APT component <jdt-apt-inbox>
Status: CLOSED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: eclipse, matthew.kusnierz
Version: 4.3   
Target Milestone: ---   
Hardware: PC   
OS: Windows 7   
Whiteboard:

Description Matt Kusnierz CLA 2013-10-03 08:55:47 EDT
I have an open project that contains an annotation processor implementation. Another project has got the output folder for this project on its annotation processors factory path. But the Advanced button shows no annotation processors and I get this error in the eclipse error log:

java.io.FileNotFoundException: C:\XXX\target\classes (Access is denied)
	at java.util.zip.ZipFile.open(Native Method)
	at java.util.zip.ZipFile.<init>(Unknown Source)
	at java.util.zip.ZipFile.<init>(Unknown Source)
	at java.util.jar.JarFile.<init>(Unknown Source)
	at java.util.jar.JarFile.<init>(Unknown Source)
	at org.eclipse.jdt.apt.core.internal.JarFactoryContainer.getServiceClassnamesFromJar(JarFactoryContainer.java:75)
	at org.eclipse.jdt.apt.core.internal.JarFactoryContainer.loadFactoryNames(JarFactoryContainer.java:53)
	at org.eclipse.jdt.apt.core.internal.util.FactoryContainer.getFactoryNames(FactoryContainer.java:80)
	at org.eclipse.jdt.apt.ui.internal.preferences.AdvancedFactoryPathOptionsDialog.createDialogArea(AdvancedFactoryPathOptionsDialog.java:104)
	at org.eclipse.jface.dialogs.Dialog.createContents(Dialog.java:775)
	at org.eclipse.jface.window.Window.create(Window.java:432)
	at org.eclipse.jface.dialogs.Dialog.create(Dialog.java:1104)
	at org.eclipse.jface.window.Window.open(Window.java:791)
	at org.eclipse.jdt.apt.ui.internal.preferences.FactoryPathConfigurationBlock.advancedOptionsDialog(FactoryPathConfigurationBlock.java:537)
	at org.eclipse.jdt.apt.ui.internal.preferences.FactoryPathConfigurationBlock.customButtonPressed(FactoryPathConfigurationBlock.java:287)
	at org.eclipse.jdt.apt.ui.internal.preferences.FactoryPathConfigurationBlock$FactoryPathAdapter.customButtonPressed(FactoryPathConfigurationBlock.java:95)
	at org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField.buttonPressed(ListDialogField.java:209)
	at org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField.doButtonSelected(ListDialogField.java:478)
	at org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField.access$0(ListDialogField.java:474)
	at org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField$2.widgetSelected(ListDialogField.java:440)
	at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:248)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1057)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4170)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3759)
	at org.eclipse.jface.window.Window.runEventLoop(Window.java:826)
	at org.eclipse.jface.window.Window.open(Window.java:802)
	at org.eclipse.ui.dialogs.PropertyDialogAction.run(PropertyDialogAction.java:158)
	at org.eclipse.jface.action.Action.runWithEvent(Action.java:499)
	at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:584)
	at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:501)
	at org.eclipse.jface.action.ActionContributionItem$5.handleEvent(ActionContributionItem.java:411)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1057)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4170)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3759)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1113)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:997)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:138)
	at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:610)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:567)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:354)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:181)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:636)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:591)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1450)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1426)

Eclipse doesn't seem to realise that this is the class output folder from an open project, and not a jar file.
Comment 1 Walter Harley CLA 2013-10-04 01:22:18 EDT
I would strongly recommend *against* trying to put an annotation processor and the code that it is processing in the same workspace.

I understand the temptation; but the bottom line here is that an annotation processor is part of the compiler, and in an incremental compilation environment like Eclipse, the compiler is loaded into the JVM all the time.  You're asking Eclipse to be able to unload and reload part of itself on demand, and the JVM just can't do that, most of the time.

You can get away with this in javac, because in between compilations the process completely shuts down.  But that's not true for Eclipse.

Best practice when you are developing Eclipse plugins - which includes annotation processors - is to have one Eclipse instance editing the plugin (or processor) code, and have that launch a second Eclipse instance that edits the target (annotated) code.
Comment 2 Matt Kusnierz CLA 2013-10-04 09:43:12 EDT
Fair enough, that makes sense
Comment 3 Walter Harley CLA 2013-10-04 22:51:39 EDT
I worked once on a project with a bug-tracking system where one possible resolution was "SBT", which stood for "Sad But True".  That would be a good resolution in this case.