This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 110040 - Need API to remove project references by name
Summary: Need API to remove project references by name
Status: RESOLVED FIXED
Alias: None
Product: javaee
Classification: Unclassified
Component: Web Project (show other bugs)
Version: 6.x
Hardware: All All
: P2 blocker (vote)
Assignee: Andrei Badea
URL:
Keywords: API
Depends on: 112441
Blocks: 101642 106904 114409
  Show dependency tree
 
Reported: 2007-07-17 17:01 UTC by _ edwingo
Modified: 2007-09-27 10:18 UTC (History)
4 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
Dialog snapshot (18.92 KB, image/png)
2007-07-17 17:14 UTC, _ edwingo
Details
Proposed API and implementation (24.79 KB, text/plain)
2007-09-19 22:39 UTC, Andrei Badea
Details
API modified to pass the opened project to the filters (28.11 KB, text/plain)
2007-09-21 15:33 UTC, Andrei Badea
Details
Patch to add visualweb/complib as a friend module (853 bytes, application/octet-stream)
2007-09-26 02:49 UTC, _ edwingo
Details

Note You need to log in before you can comment on or make changes to this bug.
Description _ edwingo 2007-07-17 17:01:01 UTC
Visualweb needs API to remove unresolved references API. This is to fix issue 101642 and affects Creator users which as
I understand is a defining feature of NB6. I believe this is a serious problem because Creator users will be confused
and not be able to use NB6.

Visualweb component libraries are implemented on top of NetBeans Libraries. In the NB Project Properties UI, there are 3
kinds of Library Refs: 1) Libraries->Compile w/o Package checkbox, 2) Libraries->Compile w/ Package checkbox, 3)
Build->Packaging. In Creator, #1 and #3 were used. In NB6, only #2 is used. The problem is in migrating Creator projects
to NB6. A unresolved reference dialog occurs and it's "in your face" and users will not know how to resolve it. The fix
is to remove the unresolved library refs in the project that are related to component libraries, however, there is not
an API or I am not able to figure out how to use the current APIs to do this.

One problem is that a
project can have a library reference in it but there may not be a
library definition in the userdir. I believe the lib refs are stored in
nbproject/project.properties. For example:

javac.classpath=\
   ${libs.jsfsupport-designtime.classpath}:\
   ${libs.webui-designtime.classpath}:\
   ${libs.jdbcsupport-designtime.classpath}:\
   ${libs.theme-default.classpath}:\
   ${libs.ProjectWithComplib_Design-time_BluePrints_AJAX_Components.classpath}:\
   ${libs.ui.complib4715.classpath}

I need some way of removing:
"${libs.ProjectWithComplib_Design-time_BluePrints_AJAX_Components.classpath}:"
and also the similar package ref in:

war.content.additional=\
   ${libs.jsfsupport-runtime.classpath}:\
   ${libs.webui-runtime.classpath}:\
   ${libs.jdbcsupport-runtime.classpath}:\
   ${libs.exceptionhandler-runtime.classpath}:\
   ${libs.theme-default.classpath}:\
   ${libs.ProjectWithComplib_Runtime_BluePrints_AJAX_Components.classpath}

I tried to create a fake library definition with the generated name and
then remove the reference but it failed. Any ideas?
Comment 1 _ edwingo 2007-07-17 17:12:54 UTC
I forgot to mention that I can construct the "name" of the unresolved references that appear in the "Resolve Reference
Problems" dialog, but I don't understand how that name corresponds to a library reference name or a library definition
(class Library) name. I know there is a localization bundle that is associated with a library definition. I'll attach an
image of the "Resolve Reference Problems" dialog which contain the lib refs that I want to remove from the project. I
can remove them manually from Project->Properties, but I need a way to do this programmatically. (I already know about
OpenProjects API.)
Comment 2 _ edwingo 2007-07-17 17:14:50 UTC
Created attachment 45233 [details]
Dialog snapshot
Comment 3 _ edwingo 2007-07-18 02:24:42 UTC
After discussing with Po-Ting, the requirement is to provide an API to remove a project reference by name so I changed
the Summary. The current API allows one to remove a reference if you have a Library which does not work if you do not
have one and creating a fake one does not seem to work either.
Comment 4 Petr Pisl 2007-08-03 10:32:32 UTC
This is new things and almost enhancements. Andrei is now trying to make web api and web project public. Andrei, if you
have time, could you look at this?
Comment 5 Andrei Badea 2007-08-03 12:17:09 UTC
Will try. Currently it seems to me that this belongs to web/project, not web/webapi.
Comment 6 Petr Jiricka 2007-08-03 14:26:36 UTC
This issue blocks a P3 bug, so shouldn't it be a P3 too?
Comment 7 Andrei Badea 2007-08-03 16:23:14 UTC
I agree, downgrading.
Comment 8 _ edwingo 2007-08-14 19:52:29 UTC
I'm concerned that downgrading this to a P3 means that this will not get fixed for NB6. I think it's important to fix
because it creates a significant migration barrier for Creator users because a misleading warning/error message appears
about broken references telling them to fix it. I realize that the web/project folks of busy, but perhaps someone else
may be able to fix it.

In order to fix the migration problem, this API needs to be available first and then other changes in visualweb need to
be made to use the API so I believe getting it fixed before beta1 is a priority. Can we change it back to a P2?
Comment 9 _ edwingo 2007-08-15 17:57:17 UTC
I understand some people who can comment on this issue are on vacation -- not sure when they will return. I am raising
this to P2 since the issue #101642 has also been raised to a P2.
Comment 10 Andrei Badea 2007-08-27 15:25:18 UTC
Suppose the API looked like an interface that you had to implement:

interface BrokenReferenceFilter {

    boolean removeReference(String name);
}

and all broken references would be, one by one, passed to this interface, and you had to return true from the method for
those references that need to be removed. Would that be enough for you? In other words, when passed a reference name
(like "${libs.ProjectWithComplib_Runtime_BluePrints_AJAX_Components.classpath}"), are you able to tell that it needs to
be removed just by looking at its name?
Comment 11 _ edwingo 2007-08-27 18:40:13 UTC
Perhaps, but I would have to try it. Should I call you to talk about this?
As far as I can tell, the Library Reference (libref) name comes from the name of the Library Definition (libdef) or
org.netbeans.api.project.libraries.Library instance when it was originally created. I know this name. Since the libdef
is kept in the userdir, it can go away and there is a stray libref that cannot be removed through an API call. As a
workaround I tried creating a fake libdef with the same name and then removing the libref and then the fake libdef, but
that did not work either.

Ideally, I would like to have a method similar to the following (Po-Ting would know details) in JsfProjectUtils, but
handling librefs instead of libdefs:

    /**
     * Remove an array of library references from a project, qualified by the type parameter.
     * @param project Project from which the library references are to be removed
     * @param library Array of Library objects from the LibraryManager registry
     * @param type Determines whether the library is to be removed from the design-time classpath or deployed
     * with the application
     * @return Returns true if at least one of the library references were successfully removed
     * @throws an IOException if there was a problem removing the reference
     */
    public static boolean removeLibraryReferences(Project project, Library[] libraries, String type) throws IOException {
        WebProjectLibrariesModifier wplm = (WebProjectLibrariesModifier)
project.getLookup().lookup(WebProjectLibrariesModifier.class);
        if (wplm == null) {
            // Something is wrong, shouldn't be here.
            return removeLibraryReferences(project, libraries);
        }

        if (type == ClassPath.COMPILE) {
            return wplm.removeCompileLibraries(libraries);
        } else if (type == ClassPath.EXECUTE) {
            return wplm.removePackageLibraries(libraries, PATH_IN_WAR_LIB);
        }

        return false;
    }
Comment 12 _ edwingo 2007-08-27 18:46:42 UTC
BTW, in your example, you gave a libref name of
"${libs.ProjectWithComplib_Runtime_BluePrints_AJAX_Components.classpath}" [1]. I believe this corresponds to a libdef
name of "ProjectWithComplib_Runtime_BluePrints_AJAX_Components" [2]. Therefore, the other parts of the name are an
implementation detail and API callers should use name #2 so they are independent of the details of the ant build system.
Comment 13 Andrei Badea 2007-08-29 17:09:07 UTC
I don't want to put this into WebProjectLibrariesModifier for a couple of reasons: it is needed for a very specific
goal, it is unlikely it will be needed by anyone else, and WPLM will need to go public at some point to enable effective
development of web frameworks. Note also that even if there was a method in WPLM to remove library references, you would
have to call it before the project shows the broken references dialog. So there would have to be a callback interface to
enable you to plug into the right point of the project opening process. I just combined this interface with the remove
method and the result is what I proposed. So, I need to know if it serves your needs.

Regarding the implementation-specific names, I can pass you the library names with the implementatation-specific parts
removed.
Comment 14 _ edwingo 2007-08-29 17:23:39 UTC
I think it should work, but I need to try it to be sure. It requires me to modify my code in a non-minor way. Could you
implement it and let me know when it is ready? Also, I would prefer the implementation-specific parts removed from the
names.
Comment 15 Petr Pisl 2007-08-30 09:06:34 UTC
I agree with Andrei.

How long time it can take to create this solution? I don't want to be in a situation, when Andrei spend 2 days with
creating the api in a branch and then we recognize that the solution is not good. 
Comment 16 _ edwingo 2007-08-30 16:12:06 UTC
ppisl: I just tried calling you and left you a voice mail message. I don't understand your comment. I would like to try
out the proposed API but I need to have it so I can test my code. Could who ever will implement it let me know when it
is available?
Comment 17 Andrei Badea 2007-08-31 13:56:14 UTC
Sorry, no ETA yet. I'm currently working on issue 112441, and I want to finish that first. When I start working on it,
implementing the API should be a matter of hours.

Comment 18 _ edwingo 2007-08-31 19:17:36 UTC
Added issue #114409 because Creator projects that consume EJBs have library refs that refer to a library def that no
longer exists in NB6 so there needs to be a way to remove these as well. This is another migration scenario.
Comment 19 Jayashri Visvanathan 2007-09-06 04:44:36 UTC
Hi  Andrei,
 Any ETA on when this issue will be fixed ?
Thanks
-Jayashri
Comment 20 Jayashri Visvanathan 2007-09-06 18:14:50 UTC
Per Petr J
"Andrei is on vacation today and tomorrow, but he is working hard on issue 112441 which is required for this fix."

thanks a lot Petr.
Comment 21 Andrei Badea 2007-09-10 15:25:44 UTC
Jayashri, no promises, but I hope to have this done for beta 2.
Comment 22 Andrei Badea 2007-09-19 22:39:38 UTC
Created attachment 49113 [details]
Proposed API and implementation
Comment 23 Andrei Badea 2007-09-19 22:44:19 UTC
I implemented the API proposed in desc11. Apply the patch to the web/project directory. The API (or rather SPI) is an
interface named org.netbeans.modules.web.project.spi.BrokenLibraryRefFilter which is registered in the default file
system (see the Javadoc). If it works for you, I will commit it to the trunk.
Comment 24 _ edwingo 2007-09-20 02:39:07 UTC
OK, thanks I will try out the API next. One thing I was talking to someone about is whether removing the library
reference will occur before the the "Broken Library References" gets displayed to the user. The removal and addition
steps should occur before the library reference check so that we can avoid the dialog. In any case, I will try it out,
but I'd appreciate knowing so I don't work on something that will eventually change.
Comment 25 Andrei Badea 2007-09-20 15:41:53 UTC
Yes, the interface is called before the Broken References dialog is invoked. Cf. desc14.
Comment 26 _ edwingo 2007-09-20 17:04:36 UTC
OK great. The complib module automatically manages a projects library defs and refs for the user since there are many.
The actual requirement is that the complib module needs a hook that gets called when a project is opened. When a project
is opened, it needs to copy jar files into the userdir and create library defs and refs and remove old legacy library
refs. I've been using the OpenProjects API for this but that won't work. It looks like the BrokenLibraryRefFilter API
can handle the removal of the old legacy library refs. Can I also do other things in the callback such as create new
library defs and refs and copy jar files into the userdir from a project? Is there a way to find out what the project of
the library ref is inside the callback?

Yesterday, someone was telling me about ProjectOpenedHook and we looked at WebProject.java:            
UILookupMergerSupport.createProjectOpenHookMerger(new ProjectOpenedHookImpl()). They said I need to be called back from
that code to get my code to work. Can I use the BrokenLibraryRefFilter as a workaround? Is there a better way to hook
into the project open event that the complib module needs to maintain libraries for a project automatically?

As I understand it OpenProjects API gets invoked *after* the broken library references dialog and I need to fix the
classpath *before* the dialog so the user does not see it. The person yesterday said I could do this with a
ProjectOpenedHook, but it may need to be coordinated with the web/project.

As a side benefit, it would help the startup time of the IDE which is another bug I've been assigned since the complib
module has code in the ModuleInstaller to add listeners for the OpenProjects API.
Comment 27 Andrei Badea 2007-09-20 17:50:08 UTC
It seems to me you can use ProjectOpenedHook to add the libraries. To do that, you register a LookupProvider in your
module layer in the Projects/org-netbeans-modules-web-project/Lookup folder. That LookupProvider will return a lookup
containing your implementation of ProjectOpenedHook. I don't think you need to coordinate with the web project on that.
You just register your implementation and it will get called.

You of course still need to use BrokenLibraryRefFilter to remove the broken library references. (Please do not use it
for anything else, such as registering libraries!) 

The call sequence when the project is opened is:

1. BrokenLibraryRefFilter is called for all broken library refs. You need to remove all the broken references here.

2. The Broken References dialog checks if it needs to show up. It won't, because you just removed all broken refs in
step #1. The project might still be uncompilable, because the new libraries are missing, but the user won't notice that,
as the project not opened yet. Note the Broken References dialog only opens if the project declares references (to other
projects, jar files, libraries) which are missing. It doesn't open if the project is uncompilable because it doesn't
declare references to resources that it needs in order to compile successfully.

3. Your ProjectOpenedHook gets called. You register your libraries here. Now the project is compilable.
Comment 28 _ edwingo 2007-09-20 18:05:08 UTC
Great, thanks for the info. How do I get a handle to the Project from the BrokenLibraryRefFilter and ProjectOpenedHook
callbacks?
Comment 29 Andrei Badea 2007-09-21 15:33:21 UTC
Created attachment 49247 [details]
API modified to pass the opened project to the filters
Comment 30 Andrei Badea 2007-09-21 15:35:28 UTC
Attached the API modified to pass the instance of the opened project to the filters. Instead of a BrokenLibraryRefFilter
you now register a BrokenLibraryRefFilterProvider. Its createFilter() method gets the project and should return a
BrokenLibraryRefFilter, which will be used to filter the references.
Comment 31 _ edwingo 2007-09-21 16:08:39 UTC
Thanks, I will try it out. But I think that only solves part of my problem. I need to add code that will copy jar files
and to add new library refs and defs in ProjectOpenedHook. To know which jars to add I need to have a handle to the
project. How do I get a Project from within ProjectOpenedHook.projectOpened()?
Comment 32 Andrei Badea 2007-09-21 20:12:23 UTC
I already answered this question in my reply to your yesterday's private e-mail:

> For ProjectOpenedHook: the method (I don't recall the name now) you implement
> in LookupProvider gets a base context lookup as its parameter. You can get
> the project from that lookup.
Comment 33 _ edwingo 2007-09-26 02:46:08 UTC
I got it to work. Thanks, I appreciate the help. Could you check it into the trunk? I did have to make one change to the
web/project project.xml file to add a friend. I'll attach a patch to the bug.
Comment 34 _ edwingo 2007-09-26 02:49:24 UTC
Created attachment 49533 [details]
Patch to add visualweb/complib as a friend module
Comment 35 Andrei Badea 2007-09-26 09:47:11 UTC
Not sure about the new friend. Since we are introducing this API in order to cleanly import Creator projects, and since
the equivalent of the Creator project in NetBeans 6.0 is the "visual JSF" framework in visualweb/project/jsf (together
with our web project), I expected you would use this API from visualweb/project/jsf. The web project has nine friends,
which is already too much. Can you attach the changes to visualweb/complib here? I need to understand better why you
need to use the API from visualweb/complib instead of visualweb/project/jsf. Thanks.
Comment 36 Andrei Badea 2007-09-26 11:08:34 UTC
Committed the broken library reference filter API.

Checking in src/org/netbeans/modules/web/project/WebProject.java;
/cvs/web/project/src/org/netbeans/modules/web/project/WebProject.java,v  <--  WebProject.java
new revision: 1.143; previous revision: 1.142
done
Checking in src/org/netbeans/modules/web/project/classpath/WebProjectClassPathModifier.java;
/cvs/web/project/src/org/netbeans/modules/web/project/classpath/WebProjectClassPathModifier.java,v  <-- 
WebProjectClassPathModifier.java
new revision: 1.7; previous revision: 1.6
done
Checking in src/org/netbeans/modules/web/project/classpath/WebProjectLibrariesModifierImpl.java;
/cvs/web/project/src/org/netbeans/modules/web/project/classpath/WebProjectLibrariesModifierImpl.java,v  <-- 
WebProjectLibrariesModifierImpl.java
new revision: 1.6; previous revision: 1.5
done
RCS file: /cvs/web/project/src/org/netbeans/modules/web/project/spi/BrokenLibraryRefFilter.java,v
done
Checking in src/org/netbeans/modules/web/project/spi/BrokenLibraryRefFilter.java;
/cvs/web/project/src/org/netbeans/modules/web/project/spi/BrokenLibraryRefFilter.java,v  <--  BrokenLibraryRefFilter.java
initial revision: 1.1
done
RCS file: /cvs/web/project/src/org/netbeans/modules/web/project/spi/BrokenLibraryRefFilterProvider.java,v
done
Checking in src/org/netbeans/modules/web/project/spi/BrokenLibraryRefFilterProvider.java;
/cvs/web/project/src/org/netbeans/modules/web/project/spi/BrokenLibraryRefFilterProvider.java,v  <-- 
BrokenLibraryRefFilterProvider.java
initial revision: 1.1
done
Checking in src/org/netbeans/modules/web/project/ui/resources/layer.xml;
/cvs/web/project/src/org/netbeans/modules/web/project/ui/resources/layer.xml,v  <--  layer.xml
new revision: 1.30; previous revision: 1.29
done
Comment 37 _ edwingo 2007-09-26 16:31:23 UTC
The main reason is that I do not own visualweb/project, someone else does (Po-Ting). However, I am responsible for bugs
in visualweb/complib which depends on visualweb/project. That means more changes and an another interface between those
two modules that we have to agree upon. Po-Ting is already on the cc list so I would like to get his take on this issue.
What do you think?
Comment 38 _ potingwu 2007-09-26 17:35:56 UTC
I agree with that no more friend modules; as I known NetBeans now has 'limit' of friends per module. Visual Web project
module is always the interface between NetBeans Project/WebProject and other Visual Web modules. Especially for this
kind of calls (libraries related), we should use visualweb/prject/jsf in between.

BTW, not only the individual owner can work on one module, there are many Visual Web developers already work/code their
need in visualweb/project/jsf. For some more sharable API, you may want to code review first. Or I can refine them later.
Comment 39 Andrei Badea 2007-09-27 10:18:27 UTC
There seems to be agreement on not adding the new friend, so since the API is now in trunk closing. Please reopen if
there is anything that still needs to be done in web/project.