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 204816 - Creation of REST web service in maven project takes a lot of time
Summary: Creation of REST web service in maven project takes a lot of time
Status: VERIFIED FIXED
Alias: None
Product: webservices
Classification: Unclassified
Component: REST (show other bugs)
Version: 7.1
Hardware: PC All
: P2 normal (vote)
Assignee: Denis Anisimov
URL:
Keywords: PERFORMANCE, THREAD
Depends on: 203737 206527
Blocks:
  Show dependency tree
 
Reported: 2011-11-08 08:39 UTC by Jiri Skrivanek
Modified: 2011-12-19 11:20 UTC (History)
2 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
Thread dump. (31.51 KB, text/plain)
2011-11-08 08:39 UTC, Jiri Skrivanek
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jiri Skrivanek 2011-11-08 08:39:25 UTC
Created attachment 112984 [details]
Thread dump.

When you try to create REST web service in maven project, it seems to be stuck for very long time. To reproduce:

- register GlassFish server to IDE
- open new project wizard and choose Maven|Web Application
- finish wizard with GlassFish target server
- open new file wizard
- choose "Web Services|RESTful Web Services from Patterns"
- finish the wizard with default values
- confirm "REST Resources Configuration" dialog with default values ("Create default Jersey REST servlet adaptor in web.xml", "Add Jersey library...", "Use server-bundled Jersey library")
- now it is stuck for several minutes (see attached thread dump)

Product Version: NetBeans IDE Dev (Build 201111070600)
Java: 1.7.0_01; Java HotSpot(TM) Client VM 21.1-b02
System: Windows XP version 5.1 running on x86; Cp1250; en_US (nb)
Comment 1 Denis Anisimov 2011-11-08 08:57:56 UTC
That's a very rare case actually:
there is no local JAX-RS api jar .
So it could happen only once: jar will be downloaded and stored locally.
Comment 2 Jiri Skrivanek 2011-11-08 09:01:53 UTC
I also tried it in NetBeans 7.0.1 and it worked quickly even for the first time.
Comment 3 Denis Anisimov 2011-11-08 09:32:00 UTC
(In reply to comment #2)
> I also tried it in NetBeans 7.0.1 and it worked quickly even for the first
> time.

It should not have relation to the version.
From the stacktrace I see the problem : it is HTTP connection.
The way how project's classpath is extended are the same for any version.
The difference could be in the artifacts and external resources:
- it is possible that in 7.0.1 you already has locally JAX-RS api jar
- or it has been downloaded without a problem with HTTP connection ( to the maven rep ).

Both cases are failed for dev version and this is result of this issue.
Comment 4 Denis Anisimov 2011-11-08 10:27:00 UTC
I'm able to reproduce.
As I said : this is a consequence of transferring Maven repository index
( you can find the progress of this operation in the status bar ).
There is no way to avoid this: its a Maven project nature.
And that happens only once. When index is fetched it becomes available 
locally and all subsequent invocation doesn't require long HTTP access 
( even with different IDE instance ).

The only way to fix this on my side is avoid running the operation 
in the AWT thread and notify the user about lengthy operation. 
The user should be able also to cancel this operation.

Please address any further issues related to this stuff to the Maven project:
the project classpath extender. This is exactly source of lengthy operation.

web-main#6184ecfda9b4
Comment 5 Quality Engineering 2011-11-09 16:08:01 UTC
Integrated into 'main-golden'
Changeset: http://hg.netbeans.org/main-golden/rev/6184ecfda9b4
User: Denis Anisimov <ads@netbeans.org>
Log: Fix for BZ#204816 - Creation of REST web service in maven project takes a lot of time
Comment 6 Jiri Skrivanek 2011-11-10 14:36:29 UTC
Just a question why the web service is created immediately if I click Cancel in "Lengthy operation in progress" dialog. It seems it is not needed to wait for it to finish.
Comment 7 Denis Anisimov 2011-11-10 15:04:19 UTC
(In reply to comment #6)
> Just a question why the web service is created immediately if I click Cancel in
> "Lengthy operation in progress" dialog. It seems it is not needed to wait for
> it to finish.

Creation of WS is not enough.
Project classpath should contain REST api jar and Jersey libraries.

Deployed project will not work without those libraries.

Lengthy operation is extending classpath with mentioned libraries.
Those libraries are not so big and their addition should not take long time.
But as I understand Maven requires to retrieve many additional artifacts : at least maven index. It happens only once if this index is not yet downloaded and stored locally in the cache.

I'm not an expert in Maven actually. All I know is : extending project classpath 
leads now to mentioned lengthy operation. I don't know is it possible to avoid this retrieval or not in this specific case. But this is Maven issue if any.
Comment 8 Jiri Skrivanek 2011-11-11 14:11:28 UTC
Jesse, could you comment on this? Something changed from NB7.0.1 and it slowed down REST web service wizard. I think it is not necessary to wait until indexes are downloaded.
Comment 9 Jesse Glick 2011-11-16 00:50:25 UTC
ProjectClassPathModifier working on a Maven project sometimes needs the repository index so it can find the coordinates of a suggested JAR addition (by SHA-1 lookup). It should therefore not be called from EQ.

Might work to just call it on a Library, rather than an ad-hoc list of JARs; then the maven-pom "volume" in the library could point directly to the desired artifact, without needing an index.
Comment 10 Jiri Skrivanek 2011-11-18 10:41:03 UTC
Thank you for your comment. From the last sentence I understand it is not necessary to wait for downloading of entire index, is it? Should I file a new issue for maven project or REST support?
Comment 11 Denis Anisimov 2011-11-18 11:29:54 UTC
(In reply to comment #10)
> Thank you for your comment. From the last sentence I understand it is not
> necessary to wait for downloading of entire index, is it? Should I file a new
> issue for maven project or REST support?

Please don't file issue against REST. 
As I said a many times : REST uses ProjectClassPathModifier to extend 
projects classpath.
The latter class has no any knowledge about project essence and how the project 
classpath is extended. Index retrieval is internal Maven implementation. 
REST doesn't know and shouldn't know about this.
The only thing which REST can do : invoke ProjectClassPathModifier outside of 
AWT thread. This is done as fix for the issue.
All other improvements should be done ( if possible ) on Maven side or 
ProjectClassPathModifier  API ( there should be some methods which allows to
avoid time consuming tasks like index retrieval if possible ).
Comment 12 Jesse Glick 2011-11-18 17:04:16 UTC
(In reply to comment #11)
> REST uses ProjectClassPathModifier to extend 
> projects classpath.
> [This] has no any knowledge about project essence and how the project 
> classpath is extended.

Not would it need any. If the Jersey JARs are available in a Library (Tools > Libraries) which properly defines a maven-pom volume (most global libraries do), Hk2JavaEEPlatformImpl$JaxRsStackSupportImpl.addJars would need only call addLibraries rather than addRoots, and the index search would be rendered unnecessary when adding to a Maven project.

It seems there is in a fact a library "Jersey 1.8 (JAX-RS RI)", a.k.a. swdp.xml, which does define maven-pom. Hk2JavaEEPlatformImpl nonetheless seems to ignore this library and add raw JARs from the GF installation. I suppose that has a benefit in that it could add a specific version of Jersey matching what GF offers, though it also would seem to make an Ant-based project less portable.
Comment 13 Denis Anisimov 2011-11-18 17:44:48 UTC
(In reply to comment #12)
> (In reply to comment #11)
> > REST uses ProjectClassPathModifier to extend 
> > projects classpath.
> > [This] has no any knowledge about project essence and how the project 
> > classpath is extended.
> 
> Not would it need any. If the Jersey JARs are available in a Library (Tools >
> Libraries) which properly defines a maven-pom volume (most global libraries
> do), Hk2JavaEEPlatformImpl$JaxRsStackSupportImpl.addJars would need only call
> addLibraries rather than addRoots, and the index search would be rendered
> unnecessary when adding to a Maven project.
> 
> It seems there is in a fact a library "Jersey 1.8 (JAX-RS RI)", a.k.a.
> swdp.xml, which does define maven-pom. 
It's NB bundled library. The REST dialog has an option what Jersey version 
to choose in the project.
>Hk2JavaEEPlatformImpl nonetheless seems
> to ignore this library and add raw JARs from the GF installation. I suppose
> that has a benefit in that it could add a specific version of Jersey matching
> what GF offers, though it also would seem to make an Ant-based project less
> portable.
It ignores it exactly by the reason : user has chosen the 
SERVER BUNDLED Jersey version. That's why server Jersey jars are used.
It is also possible to choose NB bundled Jersey. In the latter case 
NB Library will be used.
Comment 14 Jesse Glick 2011-11-18 18:09:21 UTC
Well then in the case of a Maven project, choosing "NB bundled Jersey" will always be fast, whereas choosing "Server bundled Jersey" will be fast if you already have an index for Central but will otherwise wait to download that index. There is generally no escaping the need for an index in the latter case - the REST support asked the project to add a specific list of JARs by path, and the Maven support has no way of knowing what <dependency> (if any) these would correspond to except by comparing their contents to a list of known artifacts.

A richer API in ProjectClassPathModifier might allow the REST support to negotiate with the project, perhaps directly suggesting certain artifact coordinates, or offering a Library as a fallback in case the JARs are not trivially recognized.

One improvement that the Maven impl of PCPM could make is to look for META-INF/maven/*/*/pom.properties in the JAR. Unfortunately this would only help for some of the JARs that getJerseyLibraryURLs asks for, such as mimepull.jar, but not jackson-core-asl.jar; if the non-Maven JARs are in all cases (transitive) dependencies of Maven JARs, then they could be simply ignored, but I doubt that is the case here. It is also not clear if all these JARs actually need to be in the project's classpath; if the impl JARs are supplied by the server, does it not suffice for the project to just compile against a few API JARs?
Comment 15 Denis Anisimov 2011-11-18 18:13:16 UTC
(In reply to comment #14)
> 
> One improvement that the Maven impl of PCPM could make is to look for
> META-INF/maven/*/*/pom.properties in the JAR. Unfortunately this would only
> help for some of the JARs that getJerseyLibraryURLs asks for, such as
> mimepull.jar, but not jackson-core-asl.jar; if the non-Maven JARs are in all
> cases (transitive) dependencies of Maven JARs, then they could be simply
> ignored, but I doubt that is the case here. It is also not clear if all these
> JARs actually need to be in the project's classpath; if the impl JARs are
> supplied by the server, does it not suffice for the project to just compile
> against a few API JARs?

It is not a question of compilation.
Only JSR311 jar ( JAX-RS API ) is needed to compile the project.
Other jars are required to get the project working in runtime.
Comment 16 Denis Anisimov 2011-11-18 18:25:13 UTC
Forget to say about other Jersey jars:
J2EE application will not work in the J2EE container if it has no Jersey libraries in the application.
The Jersey related jars are just bundled with the server. They are not present
in the servers classpath.

It could be a request for number of J2EE server plugin to include them into 
server's classpath. But I'm not sure is it good decision.
This question should be addressed to plugin owners.

And one more: there are some jars that are REQUIRED to get JAX-RS working on the 
server side ( basic functionality ). 
But there are also some additional jars that are required only in some cases.
F.e. jackson jars are needed to get working Jersey with json mimetypes.
Some of jars are rarely used.

Current approach for Jersey related libraries : add all of them 
into the classpath. It is not possible to realize what jars are really needed 
for developer and what are not needed.
On the other hand server bundled jars list doesn't contain usually all 
possible Jersey jars.
Comment 17 Martin Matula 2011-11-22 13:35:04 UTC
(In reply to comment #16)
> Forget to say about other Jersey jars:
> J2EE application will not work in the J2EE container if it has no Jersey
> libraries in the application.

Not true for JavaEE 6. JavaEE 6 mandates JAX-RS - i.e. all apps relying on JAX-RS API should work in a JavaEE 6 compliant container.

> The Jersey related jars are just bundled with the server. They are not present
> in the servers classpath.

Not true for GlassFish.

> It could be a request for number of J2EE server plugin to include them into 
> server's classpath. But I'm not sure is it good decision.
> This question should be addressed to plugin owners.
> 
> And one more: there are some jars that are REQUIRED to get JAX-RS working on
> the 
> server side ( basic functionality ). 
> But there are also some additional jars that are required only in some cases.
> F.e. jackson jars are needed to get working Jersey with json mimetypes.
> Some of jars are rarely used.

All these (core jars as well as jackson) are bundled and available to web apps in GlassFish.

> Current approach for Jersey related libraries : add all of them 
> into the classpath. It is not possible to realize what jars are really needed 
> for developer and what are not needed.

We have seen this causing issues with GlassFish especially when the version of jars bundled in the app is different from the version in GF - there are conflicts as the core classes are loaded from GlassFish while the jars that don't come with GlassFish are taken from the war.

> On the other hand server bundled jars list doesn't contain usually all 
> possible Jersey jars.

True.
Comment 18 Denis Anisimov 2011-11-22 14:40:49 UTC
Thanks for this information. I didn't know this.

So is it correct that all jersey related jars bundled with GF are available in the
J2EE container for application in runtime .
F.e. for GF 3.1 there are :
jackson-core-asl
jackson-jaxrs
jackson-mapper-asl
jersey-gf-server
jettison
jersey-multipart
mimepull
jersey-client
jersey-core
jersey-json
asm-all-repackaged

And one more question: are these jars contains only impl specific classes 
( for JAX-RS runtime ) or they also have some classes which user could use in 
its J2EE application ? There is of course JSR311 API which is packaged into jersey-core.jar . User uses this API classes for REST .
But there probably could be other public classes that could be used in the 
application ( not just runtime ).
I'm asking this question because IDE shows J2EE server classpath in the project. 
So the question is : what jars should be shown in this classpath ( to avoid jars which cannot be actually used in the J2EE app ).
Comment 19 Martin Matula 2011-11-22 15:25:57 UTC
(In reply to comment #18)
> Thanks for this information. I didn't know this.
> 
> So is it correct that all jersey related jars bundled with GF are available in
> the
> J2EE container for application in runtime .
> F.e. for GF 3.1 there are :
> jackson-core-asl
> jackson-jaxrs
> jackson-mapper-asl
> jersey-gf-server
> jettison
> jersey-multipart
> mimepull
> jersey-client
> jersey-core
> jersey-json
> asm-all-repackaged

These are available specifically in GlassFish. Other JavaEE containers may (and often do) contain a different implementation of JAX-RS (e.g. JBoss has RESTEasy, WAS has Wink) - so they would expose different jars and JAX-RS API would likely be the only thing in common.
I.e. if your app uses strictly JAX-RS API and no other Jersey-specific API's it will run fine on other EE6 containers. But if it uses any Jersey-specific API's it would run only if the container bundles Jersey.

> 
> And one more question: are these jars contains only impl specific classes 
> ( for JAX-RS runtime ) or they also have some classes which user could use in 
> its J2EE application ? There is of course JSR311 API which is packaged into
> jersey-core.jar . User uses this API classes for REST .
> But there probably could be other public classes that could be used in the 
> application ( not just runtime ).
> I'm asking this question because IDE shows J2EE server classpath in the
> project. 
> So the question is : what jars should be shown in this classpath ( to avoid
> jars which cannot be actually used in the J2EE app ).

Depending on what you mean by J2EE app. If you want your app to be portable to any JavaEE container, then only JAX-RS (JSR311) API can be used.
But, if you are asking about which classes are available to web applications in GlassFish in particular, then it would include also the proprietary classes in these jars (i.e. all the public classes in the above mentioned jars)
Comment 20 Denis Anisimov 2011-11-22 15:29:47 UTC
(In reply to comment #19)
> (In reply to comment #18)
> > Thanks for this information. I didn't know this.
> > 
> > So is it correct that all jersey related jars bundled with GF are available in
> > the
> > J2EE container for application in runtime .
> > F.e. for GF 3.1 there are :
> > jackson-core-asl
> > jackson-jaxrs
> > jackson-mapper-asl
> > jersey-gf-server
> > jettison
> > jersey-multipart
> > mimepull
> > jersey-client
> > jersey-core
> > jersey-json
> > asm-all-repackaged
> 
> These are available specifically in GlassFish. Other JavaEE containers may (and
> often do) contain a different implementation of JAX-RS (e.g. JBoss has
> RESTEasy, WAS has Wink) - so they would expose different jars and JAX-RS API
> would likely be the only thing in common.
> I.e. if your app uses strictly JAX-RS API and no other Jersey-specific API's it
> will run fine on other EE6 containers. But if it uses any Jersey-specific API's
> it would run only if the container bundles Jersey.
Sure.
> 
> > 
> > And one more question: are these jars contains only impl specific classes 
> > ( for JAX-RS runtime ) or they also have some classes which user could use in 
> > its J2EE application ? There is of course JSR311 API which is packaged into
> > jersey-core.jar . User uses this API classes for REST .
> > But there probably could be other public classes that could be used in the 
> > application ( not just runtime ).
> > I'm asking this question because IDE shows J2EE server classpath in the
> > project. 
> > So the question is : what jars should be shown in this classpath ( to avoid
> > jars which cannot be actually used in the J2EE app ).
> 
> Depending on what you mean by J2EE app. If you want your app to be portable to
> any JavaEE container, then only JAX-RS (JSR311) API can be used.
> But, if you are asking about which classes are available to web applications in
> GlassFish in particular, then it would include also the proprietary classes in
> these jars (i.e. all the public classes in the above mentioned jars)
Yes, I'm asking exactly about application in GF.

Thanks.