Bug 218583 - Dynamic classpath container contents are not being processed
Summary: Dynamic classpath container contents are not being processed
Status: VERIFIED INVALID
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.3.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.4 M6   Edit
Assignee: Jerome Lanneluc CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-02-11 20:16 EST by James Leone CLA
Modified: 2008-03-25 12:39 EDT (History)
2 users (show)

See Also:


Attachments
Simplified plugin with a classpath container and sample projects using that container (16.79 KB, application/octet-stream)
2008-02-11 20:16 EST, James Leone CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description James Leone CLA 2008-02-11 20:16:51 EST
Created attachment 89473 [details]
Simplified plugin with a classpath container and sample projects using that container

Build ID: 3.3.1.1 M20071023-1652

Steps To Reproduce:
1. Create a classpathInitializer plugin that has a customer classpath container.
2. Have that container conditionally toggle between a project or a JAR of the project depending on what is open in the workspace
3. Test out the plugin.  See that when the contents of the customer classpath container are expanded everything look good.  If ProjectB is open, the project is referenced.  If ProjectB is closed, the JAR version of ProjectB is in the classpath instead.
4. Close ProjectB and try to build ProjectA
5. Get an error "The project was not build due to 'Resource /ProjectB' is not open"  However, the classpath container is not reference ProjectB, it is referencing the JAR.


More information:
This is being posted per the request in newsgroups
http://www.eclipse.org/newsportal/article.php?id=22236&group=eclipse.tools.jdt#22236

I am including a stripped down version of this type of plugin to server as an example.  Included in that is another jar that has ProjectA which depends on ProjectB (or B.jar if ProjectB is closed).
Comment 1 Jerome Lanneluc CLA 2008-02-25 06:07:25 EST
The problem comes from the fact that the JDT infrastructure is not notified that the classpath entries of the container have changed. The confusion comes from the fact that the UI always shows the latest classpath entries, but the infrastructure (for performance reasons) uses the classpath entries set by the last call to JavaCore#setClasspathContainer(...).

To solve this problem, you should do as the "Plug-in Dependencies" does. I.e. register a pre-processing-resource listener with JavaCore (using addPreProcessingResourceChangedListener(..., IResourceChangeEvent.PRE_BUILD)). And when notified that the project is closed or re-opened, use JavaCore#setClasspathContainer(...) to notify the infrastructure that the container has changed.

For example:

public class DynamicClasspathInitializer extends ClasspathContainerInitializer implements IResourceChangeListener 
{
	
	{
		JavaCore.addPreProcessingResourceChangedListener(this, IResourceChangeEvent.PRE_BUILD);
	}

    @Override
    public void initialize(IPath containerPath, IJavaProject javaProject) throws CoreException
    {
        IClasspathContainer container = new DynamicClasspathContainer(javaProject);
        JavaCore.setClasspathContainer(containerPath, new IJavaProject[] {javaProject}, new IClasspathContainer[] {container}, null);


    }

	public void resourceChanged(IResourceChangeEvent event) {
		IResourceDelta delta = event.getDelta().findMember(new Path("/ProjectB"));
		if ((delta.getFlags() & IResourceDelta.OPEN) != 0) {
			try {
				initialize(new Path(Activator.CLASSPATH_CONTAINER_ID), JavaCore.create(ResourcesPlugin.getWorkspace().getRoot().getProject("ProjectA")));
			} catch (CoreException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

I'm closing this bug as INVALID. Please reopen if the solution above doesn't work for you.
Comment 2 David Audel CLA 2008-03-25 08:47:08 EDT
Verified for 3.4M6.
Comment 3 James Leone CLA 2008-03-25 12:39:11 EDT
I incorporated the sample code into my plugin and it worked out great!  Thanks again for clarifying my point of problems.  I had a feeling I was missing a step.