views:

687

answers:

2

First I want to say lots of thanks to "Rich seller" to solving my query for changing the entry order in eclipse java build path programatically.

I want to add my Library folder to java build path which has several jars in it. It should behave like a classpath container. I tried with IClasspathContainer but failed to implement.

Please help me....

Thanks in advance.

YUVRAJ.

A: 

You should define a new ClasspathContainer by implementing the org.eclipse.jdt.core.classpath.ContainerInitializerextension point. For example the org.eclipse.jdt.junit plugin defines the following in its plugin.xml

<extension
  point="org.eclipse.jdt.core.classpathContainerInitializer">
  <classpathContainerInitializer
        class="org.eclipse.jdt.internal.junit.buildpath.JUnitContainerInitializer"
        id="org.eclipse.jdt.junit.JUNIT_CONTAINER">
  </classpathContainerInitializer>
</extension>

The referenced JUnitContainerInitializer creates and initialises the two JUnit classpath containers.

Following this approach you can implement a "folder container". There is a DeveloperWorks article that shows how to do this (you'll need to register to view the article).


Update: It is possible to define a container without registering the extension point, but you have to be aware that you'll not have access to lifecycle methods to refresh the container if the contents of the folder change. It is much better to do it via the extension point.

The example below will add the "lib" folder of a project as a custom container, and add any jar files found in the folder as entries within the container. It does not manage source associations .

final String description = "My container";

IProject project = ResourcesPlugin.getWorkspace().getRoot()
        .getProject("foo");

//get the lib folder, TODO check if it exists!
final IFolder folder = project.getFolder("lib");

//define a unique path for the custom container
final IPath containerPath = new Path(
        "my.custom.CLASSPATH_CONTAINER").append(project
        .getFullPath());

IJavaProject javaProject = JavaCore.create(project);

//create a container that lists all jars in the lib folder
IClasspathContainer customContainer = new IClasspathContainer() {
    public IClasspathEntry[] getClasspathEntries() {
        List<IClasspathEntry> entryList = new ArrayList<IClasspathEntry>();
        try {
            // add any members that are files with the jar extension
            IResource[] members = folder.members();
            for (IResource resource : members) {
                if (IFile.class.isAssignableFrom(resource
                        .getClass())) {
                    if (resource.getName().endsWith(".jar")) {
                        entryList.add(JavaCore.newLibraryEntry(
                                new Path(resource.getFullPath()
                                        .toOSString()), null,
                                new Path("/")));
                    }
                }
            }
        } catch (CoreException e) {
            // TODO handle the exception
            e.printStackTrace();
        }
        // convert the list to an array and return it
        IClasspathEntry[] entryArray = new IClasspathEntry[entryList
                .size()];
        return entryList.toArray(entryArray);
    }

    public String getDescription() {
        return description;
    }

    public int getKind() {
        return IClasspathEntry.CPE_CONTAINER;
    }

    public IPath getPath() {
        return containerPath;
    }

    @Override
    public String toString() {
        return getDescription();
    }
};

//register the custom container so when we add its path it is discovered
JavaCore.setClasspathContainer(containerPath,
        new IJavaProject[] { javaProject },
        new IClasspathContainer[] { customContainer }, null);

IClasspathEntry[] entries = javaProject.getRawClasspath();

//check if the container is already on the path
boolean hasCustomContainer = false;

for (int i = 0; i < entries.length; i++) {
    if (entries[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER
            && entries[i].getPath().equals(containerPath)) {
        hasCustomContainer = true;
    }
}
if (!hasCustomContainer) {
    IClasspathEntry[] newEntries = new IClasspathEntry[entries.length + 1];

    System.arraycopy(entries, 0, newEntries, 0, entries.length);

    // add a new entry using the path to the container
    newEntries[entries.length] = JavaCore
            .newContainerEntry(customContainer.getPath());

    javaProject.setRawClasspath(newEntries,
            new NullProgressMonitor());
}
Rich Seller
Actually I have to implement it without using plugin.xml, I need to implement it with java code only.....The library folder should have the ICON like JRE libray in libraries tab of java build path. And the jars will be shown after expanding the library name.
Not sure I understand, the code needs to be implemented in a plugin to have access to the Eclipse internals. How would you implement it otherwise?
Rich Seller
Thanks Rich, I was not getting the requirement of my client, now I can tell them to use plugin.xml.once again thanks a lot, I will keep asking......good night.
A: 

My colleague implemented a classpath container which recursivly looks for jars in a given directory within the workspace, have a look at http://openscada.org/news/dx/31.05.2010154336JREJ4U.htm

The update site can be found at http://repo.openscada.org/p2/bob/R

The plugin is licensed unter LGPL V3 and you can find the source code under http://pubsvn.inavare.net/openscada/modules/bob/trunk/

Mauli