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 122989 - Need API for extending the classpath of a WebModule
Summary: Need API for extending the classpath of a WebModule
Status: RESOLVED WONTFIX
Alias: None
Product: javaee
Classification: Unclassified
Component: Code (show other bugs)
Version: 6.x
Hardware: All All
: P3 blocker (vote)
Assignee: Trey Spiva
URL:
Keywords: API
: 113123 (view as bug list)
Depends on:
Blocks:
 
Reported: 2007-11-28 16:02 UTC by Andrei Badea
Modified: 2009-11-02 11:17 UTC (History)
7 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrei Badea 2007-11-28 16:02:25 UTC
Framework support implementors often need to extend the compilation classpath of a web module (as represented by the
WebModule class) with libraries, jar files, etc. ProjectClassPathModifier can be used, but not in the case when the web
project doesn't have any Java source roots, because of the projectArtifact parameter that all PCPM methods require.
Suggest the introduction of a similar API in web/webapi, with a signature like

public void addLibraries(Library[] libraries, WebModule webModule, String classPathType);

and similar for other methods (addRoots, addArtifacts). 

The new class should be capable enough to allow removing WebProjectLibrariesModifier (currently exposed by web/project
in a friend API) -- which probably means that the signature proposed above is not enough.
Comment 1 Petr Pisl 2007-11-28 17:20:02 UTC
Yesterday I looked at the org.netbeans.modules.web.project.api.WebProjectLibrariesModifier, which is a part of friend
web project api. This interface offers the functionality, but doesn't cover the main usecase. Add libraries, roots or
artefacts on a classpath and package them to the war file. So the method should look like

public void addLibraries(Library[] libraries, WebModule webModule, String classPathType, boolean package);
Comment 2 Petr Pisl 2007-11-28 17:20:24 UTC
Yesterday I looked at the org.netbeans.modules.web.project.api.WebProjectLibrariesModifier, which is a part of friend
web project api. This interface offers the functionality, but doesn't cover the main usecase. Add libraries, roots or
artefacts on a classpath and package them to the war file. So the method should look like

public void addLibraries(Library[] libraries, WebModule webModule, String classPathType, boolean package);
Comment 3 Andrei Badea 2007-11-29 11:02:29 UTC
Right, but suggest "String pathInWar" instead of "boolean package".

Another use case is packaging a jar or library in the war file without adding it to the classpath. There could be a
second method for that, not taking a classpath type:

public void addLibraries(Library[] libraries, WebModule webModule, String pathInWar);
Comment 4 Andrei Badea 2008-02-01 16:43:32 UTC
*** Issue 113123 has been marked as a duplicate of this issue. ***
Comment 5 _ potingwu 2008-02-01 19:34:31 UTC
When we planned for NetBeans 5.5 + Visual Web Pack, we proposed and implemented the WebProjectLibrariesModifier that
ProjectClassPathModifier can't do. Please refer to the following 3 issues for more details when reimplement these APIs:

    * 73197: ProjectClassPathExtender should allow more parameters for adding libraries
    * 73198: WebProjectClassPathExtender should handle different kinds of libraries
    * 75471: Review of a new API for adding/removing entries from project classpaths
Comment 6 _ potingwu 2008-02-01 19:49:19 UTC
I think the latest issue about this WebProjectLibrariesModifier is issue#100114,
    Libraries modifier - enhancement required by visual web framework

I believe it's also been used by the Portal Pack team. I.e., Visual Web needs this function for improving the users
usage and performance while Portal Pack will not work if this function is missing. When I implemented Visual Portlet
support, it was highly depends on this function. There is one library is needed in WAR file. But if it appears in the
Classpath, the IDE is not working!
Comment 7 Jiri Prox 2008-04-11 01:19:16 UTC
moving opened issues from TM <= 6.1 to TM=Dev
Comment 8 David Konecny 2008-08-07 06:09:59 UTC
Could somebody tell me which usecases are not covered by WebProjectLibrariesModifier and who will be a client of this
new API? What's the reason for altering classpath per WebModule (let's ignore web freeform for now)? 
Comment 9 Andrei Badea 2008-08-07 10:23:46 UTC
WebProjectLibraryModifier is a friend API, so it is not generally usable.

The client is any module wanting to add a library to the classpath of the web module. Most frameworks, for example, want
to do that. Currently they have to resort to ProjectClassPathModifier, which is not applicable unless there is at least
a source root in the web module. Along for the test for the source root being plain ugly, the code also fails to modify
the classpath when there is no source root.

Another usage is by the visualweb folks, which want to bundle libraries in the WAR file, without adding them to the
classpath. If memory serves, this is currently only possible through WPLM.
Comment 10 David Konecny 2008-08-08 00:31:46 UTC
For a sake of discussion let's say WebProjectLibraryModifier is public API. In such a case is something still missing?
WPLM solves both usecases you mentioned: 
* it does not require source root; and
* it allows to add something just to WAR

What I'm after is what's missing in WebProjectLibraryModifier? If it is OK then let's try to turn it into stable API
instead of introducing a new API. Thanks.
Comment 11 Andrei Badea 2008-08-08 09:39:17 UTC
To me, whether you introduce a new API or try to make WPLM stable makes no difference (assuming that the current state
of WPLM will be removed by either of the approaches). But the stable API should also meet these constraints:

1. It should not reside in web.project, since it can be applicable to more than just the web project.

2. The client should not be aware of a notion of a project or lookup when using the API (similarly, there is no notion
of project or lookup when using ProjectClassPathModifier).

These constraints allow a web framework implementor to work solely with a WebModule and avoid the need to obtain the
project containing the web module.

WPLM meets the current use cases that I know about. Perhaps a slight design flaw is that the methods for modifying the
classpath can only modify the compilation classpath. So perhaps instead of

    addCompileLibraries(Library[]);

there should be

    addCompileLibraries(Library[], String classPathType);

similarly to methods in PCPM. But no strong opinion. I think currently ClassPath.COMPILE is the only applicable
classPathType.
Comment 12 Andrei Badea 2008-08-08 13:01:14 UTC
Eeh... instead of

    addCompileLibraries(Library[], String classPathType);

I of course meant

    addLibraries(Library[] libraries, String classPathType);
Comment 13 Petr Jiricka 2008-08-11 23:36:59 UTC
Andrei, if you say that web frameworks use WebProjectLibraryModifier API, and that this kind of API should not be tied
to web.project, then how do frameworks currently work in Maven projects? From what I saw, web framework support works
quite well with Maven.
Comment 14 Andrei Badea 2008-08-12 12:16:41 UTC
The only client of WPLM I know of is the visualweb JSF framework. It seems to test for the presence of WPLM in the
project lookup and fall back to PCPM. Assuming the Maven project type doesn't implement WPLM, the result is that runtime
libraries that should have been packed in the WAR file are added to the compilation classpath instead. Another result is
that an exception will be thrown if the project happens to have no Java source roots.
Comment 15 David Konecny 2008-08-13 04:37:17 UTC
I'm thinking along the lines of getting rid of (deprecating) WebProjectLibrariesModifier. It duplicates what's already
provided by existing ClassPathModifier API. The question is how to address what's missing:
* how to express that item being added to compilation classpath should be excluded from archive
* how to add something to archive to user defined folder but not to compilation classpath

Brainstorming:

* in a J2EE public API module introduce new classpath type "ARCHIVE" and use it to manage items to be included in
archive but not on compilation classpath

* add to ProjectClassPathModifierImplementation variations of existing methods (addLibraries, addRoots, ...) which would
have one more attribute: Properties. And similarly enhance ProjectClassPathModifier. This could all be easily done
backward compatible way. The question is how much sense would this API enhancement made to other project types.
Properties parameter would be used by clients to pass extra data with classpath modification. Available properties would
be defined on per project type basis and only project type's impl of ProjectClassPathModifierImplementation would be
required to understand them. J2EE public API module would define "ARCHIVE_PATH" and "EXCLUDE_FROM_ARCHIVE". (J2SE could
define JAR_JAVADOC and JAR_SOURCES - at the moment you can programatically add a jar to a project classpath but you
cannot programatically set its javadoc/sources. I doubt there is big need for this though. Just brainstorming possible
usecases outside of J2EE).

Re. "web project without source root" - in such a case ProjectClassPathModifier could be still used with a
projectArtifact being a file from project's web source group, no? That could be case for example of JSP framework which
does not require Java source root, right? But frameworks like JSF should refuse to be added to a project without a Java
source root.

What do you think? Does it make sense?
Comment 16 Milos Kleint 2008-08-13 06:39:44 UTC
"how to express that item being added to compilation classpath should be excluded from archive"

as far as maven projects are concerned, the concept of jars on compilation classpath that don't end up in war file is
supported by dependency scope <provided>


"how to add something to archive to user defined folder but not to compilation classpath"
not sure I follow here, define "something" and "user defined folder". is it folder in the resulting binary? (war)
Comment 17 David Konecny 2008-08-13 07:11:35 UTC
RE. '"something" and "user defined folder"' - a JAR/folder added to WAR/EAR at user specified location within the WAR/EAR
Comment 18 Milos Kleint 2008-08-13 07:45:10 UTC
not sure how that would be achieved in maven, maybe only by copying the content into "src/main/resources" or
"src/main/webapp" folder at the proper location. However it sound bad practice in case of jars anyway.
Comment 19 David Konecny 2008-08-13 08:29:23 UTC
Good point Milos. What are the use cases behind "path in archive"? What's the scenario when user want to specify extra
JAR/folder to be included in his WAR and stored in path defined by user?
Comment 20 Andrei Badea 2008-08-13 21:49:51 UTC
I do not favor the addition of a Properties magic bag to the PCPM much. It resembles a lookup, and as such it is not
intuitive to users. Worse, there are more lookup readers than providers, which is good, because telling what needs to be
put in a lookup tends to be difficult. But the Properties case is the other way around: there are more providers of
Properties, more people that won't know what to put in it.

True, the JAR Javadoc/sources use case looks valid, but that could perhaps be implemented using an ad-hoc Library
instead (one not registered in the Library Manager). Not supported currently, but looks like a simple change.

> ProjectClassPathModifier could be still used with a projectArtifact being a
> file from project's web source group

It seems it could, although it is not what most people do. Most of them would just take the first Java source group and
pass to PCPM, usually without testing that there is at least one such source group. I also don't see a good way to
document this.

> But frameworks like JSF should refuse to be added to a project without a Java
> source root.

No, they shouldn't, since the user may decide to add a source root later. Such a refusal wouldn't help anyone. It
wouldn't help the framework implementor, since he would have to test for the special case, and it wouldn't help the
user, because it would force an unnecessary order of steps on him.

> What's the scenario when user want to specify extra JAR/folder to be included
> in his WAR and stored in path defined by user?

I have no idea, really. Perhaps potingwu or ppisl (on CC) could answer this.

I see many proposals alternative to the original one, but I still haven't seen a criticism of the original proposal.
What is wrong with it, apart from the fact that it introduces a new API? (One that, I would note, is more specific, and
thus more intuitive than the generic PCPM.)
Comment 21 _ potingwu 2008-08-13 22:10:39 UTC
> What's the scenario when user want to specify extra JAR/folder to be included
> in his WAR and stored in path defined by user?

For Visual Web, it does not want to put some runtime only jar files like the deploy error-handler in the compile
classpath for performance issue. Not a showstopper however.

But for the Portal Pack, it will not work if this function is missing. There is one portal library is needed only in WAR
file. But if it appears in the compile Classpath, the project is not compilable!
Comment 22 David Konecny 2008-08-13 22:51:05 UTC
Re. "potingwu's comments" - including a JAR/folder in resulting archive but not on compilation classpath is valid
usecase. What I was questioning is why do you need to specify *location* where JAR/folder should be stored in resulting
archive? Does Portal Pack places JAR/folder somewhere else then WEB-INF/lib or WEB-INF/classes in WAR case? And in EAR
case why would destination be different from EAR's root?
Comment 23 _ potingwu 2008-08-13 22:57:05 UTC
No, I don't mean either visualweb or portal pack need to specify the location other than WEB-INF/lib or WEB-INF/classes.
The standard location is good.
Comment 24 David Konecny 2008-08-13 23:57:38 UTC
Re. "Properties magic bag" - I do not like properties approach either. It is compromise though. Alternative (as
requested by this issue) is not great either: it basically takes existing API/SPI classes (PCPM, PCPMI) makes copy of
them and adds one parameter. It is self explainable and clearer than properties approach but it is yet another API and
forces Web/J2EE dependants to use it instead of Java ClassPath API.

One of long term goals I keep in back of my mind and hope to implement once is that ClassPath API and SPI and
implementation of SPI and most of UI for customization of classpath is Java cluster business and we should get rid of it
from Web/J2EE completely. Web/J2EE should implement classpath SPI only for classpath types it introduces: WEB_SOURCES
(issue 143542) and ARCHIVE (as discussed here earlier). For Java sources it should reuse impl from Java module and just
initialize it. Similarly classpath UI customizers - it is the same UI with the same concept (list of classpath items -
jars, libraries or project - in certain order) and this UI should reside in Java cluster and be reused by Web. This UI
got over the time quite complex logic behind: classpath jar can have sources/javadoc, can be relative or variable based
path;  libraries are global or shared one; etc. And the code is duplicated in Java and Web/J2EE. But it could easily be
a resusable UI panel whose input is a JTable to show and the rest is the same (first column of the JTable would be
always classpath item). That would allow Web/J2EE to add additional columns for "Exclude from Archive" and "Path in
Archive" options. And these options would be stored as Properties in PCPM. I hope you still follow what I'm talking
about. :-)

So to answer your question Andrei what's wrong with original proposal: it introduces API which does not belong to our
cluster. Yet another alternative which would be better suited to proper cluster separation: keep all classpath API in
Java cluster and in Web/J2EE define "packaging API" which would allow clients to say which classpath items should be
packaged and which not. I think architecture wise this would be better decision. Would you agree?

Btw. Andrei do you agree that JAR/folder to be packaged but not added to compilation classpath could be implemented as
dedicated classpath type ("ARCHIVE" classpath type)? Instead of dedicated methods as WebProjectLibrariesModifier does.

Re. "No, they shouldn't, since the user may decide to add a source root later." - possible, but such a design decision
has consequences. What is the usecase for web project without Java source root? I think (challenge me please) a Web
project without Java source root makes only sense if it is a "static" web application - web application with HTML, JS,
JSP (that's why JSP framework is applicable here IMO). Once you want to use JSF, Spring, Struts framework you have to
have a source root (a "dynamic" web application). Clarifying this and be more strict might help web framework writers to
decide whether they rely on Java source root or just on web root.
Comment 25 Milos Kleint 2008-08-14 07:49:36 UTC
I can imagine a web project that has all the java classes in a jar dependency? Therefore it doesn't need it's own
sourceroot?


On an unrelated note, I agree with David's outline on how to unify the currently copied code. However it's always hard
to draw an API line across UIs..
Comment 26 Andrei Badea 2008-08-14 10:45:37 UTC
> It is self explainable and clearer than properties approach but it is yet another API 
> and forces Web/J2EE dependants to use it instead of Java ClassPath API.

There is nothing wrong in that, except perhaps for the fact that they have to find it. But it is true that the fact that
if there is no usecase for the pathInWar, the API would get a lot more similar to PCPM.

> ClassPath API and SPI [...] is Java cluster business and we should get rid of
> it from Web/J2EE completely.

That I agree with. But I believe the cluster separation doesn't matter in this case. If you look at the API as one for
extending a web module (as defined by the WebModule class), it can be provided by the Web/Java EE modules.

> Btw. Andrei do you agree that JAR/folder to be packaged but not added to
> compilation classpath could be implemented as dedicated classpath type
> ("ARCHIVE" classpath type)?

At the code level, sure it can. As long as you are happy with telling users to use an API with "classpath" in its name
to add something to the archive, i.e., specifically *not* on the classpath. Once I even considered using
ClassPath.EXECUTE for this, but I didn't investigate it further, so I don't know what problems it may have. But it is a
good name at least when the jars are added to WEB-INF/lib, since they would really be added to the classpath at runtime.
Comment 27 Trey Spiva 2008-11-18 22:56:11 UTC
Move to later
Comment 28 Quality Engineering 2009-11-02 11:17:39 UTC
NetBeans.org Migration: changing resolution from LATER to WONTFIX