I tried changing it to be the last field, per your recommendation, but
alas, it did nothing. I both tried changing the order of the
attributes, and putting the accessor methods last (was first).

P.S. This was using Glassfish 2.1.1. I used to be able to deploy and
work in Glassfish 3.1.1, but GF 3 now fails on writing the WADL to the
outputstream with "WebappClassLoader unable to load resource
[java.util.TreeSet], because it has not yet been started, or was
already stopped". Any idea if this bug is of a recent date?


Regards
Carl-Erik

2012/10/8 Sergey Beryozkin <[email protected]>:
> Hi Carl-Erik
>
> On 08/10/12 21:31, Carl-Erik Kopseng wrote:
>>
>> I think I might have found some kind of bug related to QueryParam, but
>> to make sure, I am posting it here first for input.
>>
>> Using QueryParam("") MyClass myInput is usually a nice shortcut for
>> generating a WADL where the fields of MyClass are documented with type
>> and name. This has worked nicely for any classes composed of simple
>> fields, such as integers, doubles, Strings, etc, and for complex
>> Collection-ish fields (such as MyFoo[] foos), the type is not shown in
>> the WADL.
>>
>> Today I had a class where one field is complex, and not of a array or
>> collection type, and to my surprise, the fields of this complex field
>> were shown. That was new to me! Unfortunately, all the other
>> parameters (fields of the input object) were _not_ shown. If my
>> description seems a bit unclear, I pasted the code and resulting wadl
>> snippet at http://pastebin.com/zqPi7Rfd and  below. Is this a bug or a
>> really weird feature? Using CXF JAX-RS 2.6.2
>>
>> calculateCurrencyExchange(@QueryParam("") CurrencyExchangeInput input){
>>       ...
>> }
>>
>> class ExchangeableCurrenciesInput {
>>
>>         private ExchangeType type;
>>         private boolean showExchangeRates;
>>         private boolean showMargins;
>>         private boolean showProxyCurrencies;
>>
>>          ...
>> }
>> class ExchangeType {
>>
>>         private Long id;
>>         private String name;
>>         private String description;
>>          ...
>> }
>>
>> <resource path="/getExchangeableCurrencies">
>> <method name="GET">
>> <request>
>> <param name="type.name" style="query" type="xs:string"/>
>> <param name="type.id" style="query" type="xs:long"/>
>> <param name="type.description" style="query" type="xs:string"/>
>> </request>
>> <response>
>> <representation mediaType="application/json"/>
>> </response>
>> </method>
>> </resource>
>>
> I have a test with simple and complex fields, but that may be a bit brittle,
> the actual code dealing with that, may be even an ordering issue, example,
> having 'private ExchangeType type' as the last field may work better, I'll
> investigate
>
> Sergey
>
> --
> Sergey Beryozkin
>
> Talend Community Coders
> http://coders.talend.com/
>
> Blog: http://sberyozkin.blogspot.com



-- 
Carl-Erik Kopseng

(+47) 40065078
skype: carl.erik.kopseng
blogg: oligofren.wordpress.com
##########################
Ser ikke skogen for bare syntakstrær
Stacktrace:

[#|2012-10-09T10:21:25.918+0200|SEVERE|oracle-glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=18;_ThreadName=Thread-8;|java.lang.IllegalStateException:
 WEB9031: WebappClassLoader unable to load resource [java.util.TreeSet], 
because it has not yet been started, or was already stopped
        at 
org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1401)
        at 
org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1359)
        at org.apache.cxf.jaxrs.impl.MetadataMap.keySet(MetadataMap.java:137)
        at 
org.apache.cxf.transport.http.Headers.copyToResponse(Headers.java:398)
        at 
org.apache.cxf.transport.http.AbstractHTTPDestination.flushHeaders(AbstractHTTPDestination.java:524)
        at 
org.apache.cxf.transport.http.AbstractHTTPDestination.flushHeaders(AbstractHTTPDestination.java:502)
        at 
org.apache.cxf.transport.http.AbstractHTTPDestination$WrappedOutputStream.onFirstWrite(AbstractHTTPDestination.java:666)
        at 
org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:47)
        at 
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.writeResponseToStream(JAXRSOutInterceptor.java:495)
        at 
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(JAXRSOutInterceptor.java:199)
        at 
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse(JAXRSOutInterceptor.java:146)
        at 
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage(JAXRSOutInterceptor.java:84)
        at 
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)
        at 
org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:77)
        at 
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)
        at 
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
        at 
org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:211)
        at 
org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:213)
        at 
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:154)
        at 
org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:130)
        at 
org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:221)
        at 
org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:146)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
        at 
org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:197)
        at 
org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
        at 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
        at 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
        at 
no.cicero.cfp.ws.rest.filters.SecurityFilter.doFilter(SecurityFilter.java:112)
        at 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
        at 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
        at 
no.cicero.cfp.web.filters.ErrorLoggingFilter.doFilter(ErrorLoggingFilter.java:69)
        at 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
        at 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
        at no.cicero.cfp.web.filters.TimingFilter.doFilter(TimingFilter.java:79)
        at 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
        at 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
        at 
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
        at 
org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:175)
        at 
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java)
        at 
org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
        at 
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
        at 
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
        at 
org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
        at 
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
        at 
com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
        at 
com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
        at 
com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
        at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
        at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
        at 
com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
        at 
com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
        at 
com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
        at 
com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
        at 
com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
        at 
com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
        at 
com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
        at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
        at 
com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
        at 
com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
        at java.lang.Thread.run(Thread.java:680)
|#]

String captured just before os.write()
<application xmlns="http://wadl.dev.java.net/2009/02"; 
xmlns:xs="http://www.w3.org/2001/XMLSchema";><grammars></grammars><resources 
base="http://localhost:8080/cfp/6/ws/rest";><resource 
path="/currency_exchange"><resource path="/calculateCurrencyExchange"><method 
name="GET"><doc>13.3 Calculates currency exchange possibly via the given proxy 
currency</doc><request><param name="fromamount" style="query" 
type="xs:double"/><param name="fromcurrencycode" style="query" 
type="xs:string"/><param name="proxycurrencycode" style="query" 
type="xs:string"/><param name="tocurrencycode" style="query" 
type="xs:string"/><param name="toamount" style="query" type="xs:double"/><param 
name="exchangetypeid" style="query" 
type="xs:long"/></request><response><representation 
mediaType="application/json"></representation></response></method></resource><resource
 path="/getExchangeableCurrencies"><method name="GET"><doc>13.2 Get all 
available currencies for the given currency exchange type</doc><request><param 
name="type.name" style="query" type="xs:string"/><param name="type.id" 
style="query" type="xs:long"/><param name="type.description" style="query" 
type="xs:string"/></request><response><representation 
mediaType="application/json"></representation></response></method></resource><resource
 path="/getOfferedCurrencyExchangeTypes"><method name="GET"><doc>13.1 Get all 
available currency exchange types</doc><response><representation 
mediaType="application/json"></representation></response></method></resource></resource></resources></application>


JAXRSOutInterceptor
...
    private void writeResponseToStream(OutputStream os, Object responseObj) {
        try {
            byte[] bytes = responseObj.toString().getBytes("UTF-8");
            os.write(bytes, 0, bytes.length);
        } catch (Exception ex) {
            LOG.severe("Problem with writing the data to the output stream");
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
    }

Reply via email to