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 136912 - WS Stack API
Summary: WS Stack API
Status: RESOLVED FIXED
Alias: None
Product: webservices
Classification: Unclassified
Component: Code (show other bugs)
Version: 6.x
Hardware: All All
: P3 blocker (vote)
Assignee: apireviews
URL:
Keywords: API_REVIEW
Depends on:
Blocks:
 
Reported: 2008-06-10 13:45 UTC by Milan Kuchtiak
Modified: 2008-07-18 18:03 UTC (History)
10 users (show)

See Also:
Issue Type: TASK
Exception Reporter:


Attachments
Architecture document (56.11 KB, text/plain)
2008-06-10 14:00 UTC, Milan Kuchtiak
Details
Javadoc (98.00 KB, application/octet-stream)
2008-06-10 14:02 UTC, Milan Kuchtiak
Details
Arch (56.11 KB, text/html)
2008-06-10 14:05 UTC, Milan Kuchtiak
Details
Updated Javadoc (89.45 KB, application/octet-stream)
2008-06-19 10:28 UTC, Milan Kuchtiak
Details
Latest Javadoc (119.38 KB, application/octet-stream)
2008-06-20 18:02 UTC, Milan Kuchtiak
Details
Latest WS Stack API Javadoc (124.28 KB, application/octet-stream)
2008-06-25 15:17 UTC, Milan Kuchtiak
Details
Latest javadoc that accepts proposal from Andrei (111.54 KB, application/octet-stream)
2008-06-26 12:59 UTC, Milan Kuchtiak
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Milan Kuchtiak 2008-06-10 13:45:58 UTC
IZ entry for API review for WS Stack API.
The WS Stack API is a contract between web service functionality supported in IDE and web service capability of
particular J2EE Server.

See the wiki page ; http://wiki.netbeans.org/WebServicesServerApi

REVIEWERS: phejl, abadea, jlahoda, mgrebac, jungi
Comment 1 Milan Kuchtiak 2008-06-10 14:00:15 UTC
Created attachment 62617 [details]
Architecture document
Comment 2 Milan Kuchtiak 2008-06-10 14:02:16 UTC
Created attachment 62618 [details]
Javadoc
Comment 3 Milan Kuchtiak 2008-06-10 14:05:21 UTC
Created attachment 62619 [details]
Arch
Comment 4 Milan Kuchtiak 2008-06-10 14:09:27 UTC
Intended for Netbeans 6.5.
Comment 5 Milan Kuchtiak 2008-06-11 09:30:14 UTC
Could you please review the materials until Thursday next week (19.06.2008). 
I am not sure whose responsibility is to set up the reviewers meeting.
Nevertheless, I suggest to meet on Thursday (19.06.2008) at 3 pm.
Comment 6 Jaroslav Tulach 2008-06-13 09:45:26 UTC
Y01 no <api type='export' group='java' /> in the arch document, see http://openide.netbeans.org/tutorial/api.html
Y02 no <usecase /> in arch document, just on the wiki
Y03 the API usage is quite verbose. Shall not you have a method public static WsStack WsStack.getStack(Project p, 
String name) directly in your API, if it is really useful?
Y04 I can see some interface in the API, what is its evolution story? Will you be able to enhance the contract in 
future?
Comment 7 Milan Kuchtiak 2008-06-13 10:46:18 UTC
Thank You.

Y01: fixed
Y02: it's already there:
 <answer id="arch-usecases">
  <p>
   ...
   Use cases:
  </p>
   <usecase id="1" name="JAX-WS Stack in GlassFish">
     ...
   </usecase>
   <usecase id="2" name="JAX-RPC Stack in GlassFish">
     ...
   </usecase>
   <usecase id="3" name="JAX-WS Stack in Tomcat">
     ...
   </usecase>
 </answer>
Y03: I didn't want to depend on Project API. We can discuss about that on reviewers meeting.
Y04: You're not the only one who noticed that. I'll change it to final class and move interface to SPI.
Comment 8 Milan Kuchtiak 2008-06-19 10:26:03 UTC
Attaching updated version of WS Stack API.

based on the comments from REST team (Peter Liu, Ayub Khan) I removed constants from WS Stack object since these
constants are mostly related to JAX-WS/JAX-RPC technology. Now the idea is that all constants will be specified by
particular technology support (e.g. in specific REST module).

I also simplified entire WS Stack API and added WSTool API and SPI class.
Comment 9 Milan Kuchtiak 2008-06-19 10:28:03 UTC
Created attachment 63066 [details]
Updated Javadoc
Comment 10 Milan Kuchtiak 2008-06-19 10:39:51 UTC
The API Review meeting is held today at 3 PM CET time - in Alexandria room (2nd floor - 2330)
Comment 11 Martin Grebac 2008-06-19 10:43:42 UTC
MG01: Since this api involves server integration area, why there's nobody form the gf plugin team on the review?
Comment 12 Martin Grebac 2008-06-19 11:16:35 UTC
MG02: WSTool spi suggests strongly use for tools (like wsimport, ...). However, there are different sets of artifacts
that applications need to locate on the server as well (like security keystores, ...). That kind of api is missing in
j2eeserver itself. I'm adding this comment because current tool-related api is (mis)used for this purpose and requires a
replacement.

MG03: I assume the server may return several implementations of the WS stacks. What are the conditions/consequences?

MG04: I think it might be good idea to start from a more high-level 'Stack' abstract classes being used on top of
WSStack, such that a sever might decide to implement a stack (grails stack, groovy stack, jaxb stack, ...) which doesn't
necessarily need to be connected to web services.

MG05: Looking at the usecase1, I don't see notions of metro stack. I assume the JAXWSStack described there will be
expected to provide all the WSStack.Features/WSStack.Tools contained in the Metro stack. Or is the idea to provide
several instances of stacks from one server instance?
Comment 13 Petr Hejl 2008-06-19 12:32:48 UTC
PH01: I thought this will be _stack_ support (implemented for JDK and IDE too) is it wise in such case to talk
everywhere in the api about server and name it J2EE Server API for WS? Am I missing something?
PH02: Accessors shouldn't be part of the API.
Comment 14 Martin Grebac 2008-06-19 12:37:42 UTC
I can't join sooner than 3.30.
Comment 15 Milan Kuchtiak 2008-06-19 12:55:26 UTC
MG01: good point - Though we have P.Hejl(J2EE guy) in staff I'll add a GlassFish expert (Vince) on CC

MG02 : the latest version is more generic - I removed all constants from WSStack class

MG03 : Yes, the client will get a collection of WSStack objects from J2EE Server lookup, then the right one will be
selected based on WSStack.getName()

MG04 : The J2EEServer lookup can contain anything. I am not aware what does the Groovy support require. There can be
another type of stack created for Groovy - not necessarily implementation of WS Stack API.

MG05 : Last version of WS Stack API is quite generic. For Metro there are 2 options.
         1. There can be a specific Metro stack created for Metro in J2EE Server Plugin
         2. Metro stack can be a specific JAX-WS stack, where stack.isFeatureSupported(JaxWsFeature.METRO) returns true

PH01 : Right, we may rename it to WS Stack API

PH02 : Right, though these classes are not in public packages, I'll remove those from Javadoc
Comment 16 Petr Hejl 2008-06-19 13:05:49 UTC
PH03: I think common naming convention for API/SPI classes is Something/SomethingImplementation (instead of
Something/SomethingSPI).
Comment 17 Andrei Badea 2008-06-19 14:00:42 UTC
[AB01] The documentation doesn't describe the need for a common stack class. An alternative approach could have been for
each WS technology to define its API, like JAXWSStack, RESTStack, etc. That way you could get rid of the getName()
method. Regarding [MG04]: what do a Groovy stack and a JAXB stack have in common?

[AB02] Use cases are not described in sufficient detail. For example, the purpose of WSStack.Provider and
WSStack.isFeatureSupported() is not clear.

[AB03] How does a client retrieve a WSStack instance?

[AB04] WSTool.getClassPathEntries() should perhaps return a ClassPath instead, or at least it should return URL's.

[AB05] Why is there a WSStackFactory method taking a WSStack.Provider instead of there just being a
WSStackSPI.getProvider() method?

[AB06] NetBeans practice calls for WSStackSPI to be called WSStackImplementation. Same for WSToolSPI.

[AB07] WSStack.getWSStackProvider() should be named getProvider().
Comment 18 Martin Grebac 2008-06-19 15:02:35 UTC
I'm sorry I couldn't join a meeting, had to attend a different one.

Re AB01: They provide stack which has a name, has a version, provides tools which might need classpath (xjc, schemagen,
groovyconsole, java2groovy, grails, ...)
Comment 19 Andrei Badea 2008-06-20 12:04:26 UTC
TCR's and TCA's from the review:

TCR: rename WSStackSPI to WSStackImplementation, similar for WSTool.

TCR: WSStackSPI.getWSTool() should return WSTool, not WSToolSPI.

TCR: remove WSStackFactory.createWSStack(WSStackSPI).

TCR: document all undocumented public methods.

TCR: document use cases in the architecture document properly.

TCA: getVersion() should return a better value than a String.

TCA: evaluated use cases and decide whether WSStack should be immutable or not. Currently it is partially immutable: the
version can change, but the provider can't.

TCA: rename WSStack.getWSStackProvider() to getProvider().
Comment 20 Milan Kuchtiak 2008-06-20 18:02:44 UTC
Created attachment 63175 [details]
Latest Javadoc
Comment 21 Milan Kuchtiak 2008-06-20 18:12:02 UTC
I attached the latest version of Javadoc that implements almost all TCRs/TCAs .
The main change is WSStackProvider class (related to AB01):

- WSStackProvider enables to obtain WSStack instances using the getWsStack(Class<T> clazz) method that gives much more
freedom and flexibility to particular WS Stack type to provide some additional information.

Thanks Andrei for your participation on the design.

I still need to update architecture document (use cases)
Comment 22 Milan Kuchtiak 2008-06-23 09:23:42 UTC
I realized, the system is not enough modular now.

There are 4(5) types of modules than need to be considered in the system :

Type A: WS Stack API : API that is discussed here
Type B: J2EE Server API
Type C: J2EE Server plugin module (e.g. GlassFish Plugin)
Type D: WS technology (stack) module : specifies the basic features and libraries locations of particular WS technology
        (e.g. JaxWsStack module for jax-ws technology
Type E: Specific WS Support module (e.g. JAX-WS support) that provides support for particular technology

Note: Modules D and E can be merged into one module.

The expectation is that modules C, D(and E) should be pluggable and cannot depend on each other directly.
These are final dependencies :
A - independent
B - independent
C - depends on A and B
D - depends on A
E - depends on A,B and D

This is an idea how WSStackProvider can be modularized :

1.
WSStackProvider - SPI - interface can have the following methods :
-------
<T> WSStack<T> getWSStack(Class<T> clazz, File serverRoot, String serverName);
Collection<WSStack<?>> getWSStacks(File serverRoot, String serverName);
-------
It's a responsibility of Module type D (WS Technology) to implement the interface, based on parameters passed from the
server plugin. The implementation should be registered into global lookup (as a global "WSStackProvider" service)

2. ServerWSStackProvider(or J2eeServerWsStackProvider) - API class - can be the following (final) class:
-------
public <T> WSStack<T> getWSStack(Class<T> clazz) {
  ...
}
public Collection<WSStack<?>> allWSStacks() {
  ...
}
-------
It's a responsibility of module C (Server Plugin) to create an instance of this class and register it into it's lookup.
The implementation of this class will delegate do WSStackProvider implementations collected from the global lookup.
J2ee server is responsible for passing correct parameters (serverRoot and serverName).

Finally, the client code, implemented in module E(possibly D) is taking ServerWSStackProvider instance from J2EE Server
lookup(J2eePlatform lookup) then retrieves WSStack from this (singleton)instance.
The class type parameter - required in getWSStack() method - will be obtained from module D.

Hopefully, this will work. The last version requires only a slight modification.
Comment 23 Milan Kuchtiak 2008-06-24 11:11:27 UTC
Based on discussion with Lukas and Andrei it's better to use layer.xml to register WSStackProvider implementation
instead of META-INF/services.

Suggested layer.xml structure:

<folder name="WSStacks">
  <folder name = "Tomcat50> <!-- server Id -->
    <file name="org-netbeans-modules-websvc-jaxws-wsstack-TomcatJaxWsStackProvider.instance">
      ...
    </file>
  </folder>
  <folder name = "Tomcat55"> <!-- server Id -->
    <file name="org-netbeans-modules-websvc-jaxws-wsstack-TomcatJaxWsStackProvider.instance">
      ...
    </file>
  </folder>
  <folder name = "J2EE"> <!-- server Id -->
    <file name="org-netbeans-modules-websvc-jaxws-wsstack-GlassFishJaxWsStackProvider.instance">
      ...
    </file>
  </folder>
</folder> <!-- WSStacks -->

Therefore, the serverName parameter is useless in WSStackProvider methods, They can be simplified : 

<T> WSStack<T> getWSStack(Class<T> clazz, File serverRoot);
Collection<WSStack<?>> getWSStacks(File serverRoot);

Finally, the API class ServerWSStackProvider (lookig for better name) should have a private constructor:

private ServerWSStackProvider(String serverId, File serverRoot) {
} 

and there should be a support SPI class (WSStackSupport) with a static method:

ServerWSStackProvider createServerWSStackProvider(String serverId, File serverRoot);

Question is whether the serverRoot File is enough to pass to WSStackProvider instance.

Comment 24 Milan Kuchtiak 2008-06-24 11:38:58 UTC
Based on discussion with Lukas and Andrei it's better to use layer.xml to register WSStackProvider implementation
instead of META-INF/services.

Suggested layer.xml structure:

<folder name="WSStacks">
  <folder name = "Tomcat50> <!-- server Id -->
    <file name="org-netbeans-modules-websvc-jaxws-wsstack-TomcatJaxWsStackProvider.instance">
      ...
    </file>
  </folder>
  <folder name = "Tomcat55"> <!-- server Id -->
    <file name="org-netbeans-modules-websvc-jaxws-wsstack-TomcatJaxWsStackProvider.instance">
      ...
    </file>
  </folder>
  <folder name = "J2EE"> <!-- server Id -->
    <file name="org-netbeans-modules-websvc-jaxws-wsstack-GlassFishJaxWsStackProvider.instance">
      ...
    </file>
  </folder>
</folder> <!-- WSStacks -->

Therefore, the serverName parameter is useless in WSStackProvider methods, They can be simplified : 

<T> WSStack<T> getWSStack(Class<T> clazz, File serverRoot);
Collection<WSStack<?>> getWSStacks(File serverRoot);

Finally, the API class ServerWSStackProvider (lookig for better name) should have a private constructor:

private ServerWSStackProvider(String serverId, File serverRoot) {
} 

and there should be a support SPI class (WSStackSupport) with a static method:

ServerWSStackProvider createServerWSStackProvider(String serverId, File serverRoot);

Question is whether the serverRoot File is enough to pass to WSStackProvider:getWSStack method. 
One another idea (Andrei) is to pass another object (J2eePlatform Lookup).

Comment 25 Milan Kuchtiak 2008-06-25 15:17:31 UTC
Created attachment 63431 [details]
Latest WS Stack API Javadoc
Comment 26 Andrei Badea 2008-06-26 09:52:26 UTC
[AB08] +1 on allowing WS stacks to be implemented outside the server plugin modules, but -1 on the proposed way to
register such implementations. You are introducing a private contract between all server plugin modules and the web
services support modules. And even if it's not private, it is too limited, since in only supports WSStack's. Moreover,
the plugin modules will have to depend on the WS Stack API, but better if this dependency can be avoided.

Instead, I suggest a generic way to add instances to J2eePlatform.getLookup(), similar to the one used in projects.

In j2eeserver define an interface for a lookup provider:

interface LookupProvider {
    
    Lookup createAdditionalLookup(Lookup baseLookup, File serverRoot);
}

Define a place in the system file system to register such interfaces:

J2EE
    DeploymentPlugins
        <server id>
            J2eePlatformLookup

At runtime, each server plugin calls all applicable LookupProvider's (for each server instance) and merges their return
values into a single lookup returned by J2eePlatform.getLookup().

Then a web services support module (say JAX-WS) wanting to implement a WS Stack for a server would do the following.

Implement a WSStackImplementation<JAXWS>, create a WSStack<JAXWS> from it. Create a JAXWSLookupProvider class
implementing LookupProvider. Return a lookup containing WSStack<JAXWS> from createAdditionalLookup(). The WSStack<JAXWS>
instance would then appear in J2eePlatform.getLookup().

Since there can be many WSStack instances in the lookup, how does a client retrieve the right one?

Introduce a static method in WSStack

<T> WSStack<T> findWSStack(Lookup context, Class<T> clazz);

This method will take all WSStacks in the lookup and find the one with the right class. But since the values of the type
parameter is erased at runtime, WSStack needs to know its class token.

Modify WSStackFactory.createWSStack() to also take a Class<T> parameter. Store this parameter in WSStack and use it in
findWSStack() above.

WSStackProvider can then be completely removed.
Comment 27 Milan Kuchtiak 2008-06-26 11:10:28 UTC
Good stuff Andrei :

- no need for WSStackProvider
- no need for WSStackQuery (Group) - this will be replaced by WSStack.findWSStack() - static method
- moreover, WSStack implementation disposes with J2eePlatform lookup which is flexible enough to take any farther
information from the server.

This requires additional support from J2EEServer (implement LookupProvider functionality).

Thanks again.

The only inconvenience here s to register the J2EEPlatform's LookupProvider under each server id, which is not a big
deal I think.
Comment 28 Milan Kuchtiak 2008-06-26 12:59:00 UTC
Created attachment 63509 [details]
Latest javadoc that accepts proposal from Andrei
Comment 29 Milan Kuchtiak 2008-07-18 18:03:03 UTC
I think, the development is finished: see the last javadoc and arch.xml changes:
http://hg.netbeans.org/main?cmd=changeset;node=b23d5dc2ec09
All TCRs/TCAs were accepted.