users@jersey.java.net

Re: ServletContainer jar scanning exception

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Wed, 02 Jan 2008 14:33:12 +0100

Hi Richard,

Richard Wallace wrote:
> I was revisiting this issue recently to try and get it working with 'mvn
> jetty:run'

Glad you raised this issue again since recently i was wondering what we
could do about it :-)


> and decided to have a look at how the struts2 codebehind
> plugin works. I pretty much needs to do the same thing, scan for
> classes implementing an interface or with a certain annotation. To do
> this they use the ResolverUtil class from XWork2
> (http://svn.opensymphony.com/svn/xwork/trunk/src/java/com/opensymphony/xwork2/util/ResolverUtil.java).
>
>
> The basic idea seems to be that you can use the
> ClassLoader.getResources() method with a package name and it will give
> you a list of resources in that package.
>

I did not know that ClassLoader.getResources could return a URL to a
directory where class files reside!

For example:

Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().
     getResources("");
while(urls.hasMoreElements()) {
   System.out.println(urls.nextElement());
}

Unfortunately there seems no consistent way to get the complete set of
base URLs to stuff of the class loader :-( and therefore no zero-config
approach.


> So there should be no need to specify where the class files and jars are.
>

But instead package names do need to be specified.

Arguably this requires more configuration knowledge that is likely to
change, for example if i add a new resource in a different package to my
existing resources then i need to include that package (and if i
refactor then i need to change it). Compile-time tools can help but they
do complicate the build and deploy process (which is why we moved away
from them). I think this gets more complicate when we consider message
readers and writers (see end of email).

I very much like the idea of a zero-config build and deploy approach by
default.

Hmmm... perhaps we could do the following:

Have a PackageResourceConfig that takes a list of package names that are
transformed into URLs (like what Struts does) that are then scanned for
classes (using ASM). The PackageResourceConfig class and the package
names for the PackageResourceConfig instance could be passed as servlet
init-params. That should work consistently for the two forms of Jetty
deployment.

What do you think?

BTW i am curious if you tried setting the servlet init-param:

   "com.sun.ws.rest.config.property.ResourcePaths"

to the absolute location of where the class files reside in the dev
deploy case? i.e. whether the Servlet.getRealPath works in such cases.



For 0.6 the ResourceConfig stuff needs to be refactored to also return
message readers and writer classes. Dynamically finding such things is
IMHO better that using META-INF/services. Then we can also defer
creation of readers/writers to an IoC framework.

Paul.

> Rich
>
> Paul Sandoz wrote:
>> Richard Wallace wrote:
>>> Alright, I did a bit more digging. I hadn't noticed that check for
>>> if it is a directory. The problem is that since I'm running jetty
>>> with the maven-jetty-plugin jetty:run target (super useful for
>>> debugging), the /WEB-INF/lib and /WEB-INF/classes directories don't
>>> exist.
>>
>> It is odd that context.getRealPath("/WEB-INF/lib") is actually
>> returning something non-null though, so in some sense they must exist
>> "Jim, but not as we know it".
>>
>>
>>> With the jetty:run target, the plugin doesn't assemble the war, it
>>> runs everything in place and tells jetty what it should use for the
>>> classpath.
>>>
>>
>> OK. See the JavaDoc of:
>>
>> com.sun.ws.rest.spi.container.servlet.ServletContainer
>>
>> perhaps you could set the init-param:
>>
>> com.sun.ws.rest.config.property.ResourcePaths
>>
>> to point to the relevant locations? I guess it all depends on what
>> base path for context.getRealPath() with Jetty for a non-standard
>> deployment config.
>>
>> Another workaround is to create your own class that extends
>> DynamicResourceConfig with an empty public constructor that configures
>> things from the java.class.path system property (see the
>> com.sun.ws.rest.api.container.ContainerFactory code). Then set up the
>> web.xml to point to this class using the "webresourceclass" init-param.
>>
>>
>>> This is what is causing the scanning code to die. The solution is to
>>> use the jetty:run-war target instead. The bad thing about running
>>> the plugin that way is that changes to things like jsps and templates
>>> don't just automatically get used, the webapp has to be redeployed.
>>> A pain but something I can live with.
>>>
>>> As you said, more error handling code would have made this much
>>> easier to track down.
>>>
>>
>> Tis done.
>>
>> Paul.
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>

-- 
| ? + ? = To question
----------------\
    Paul Sandoz
         x38109
+33-4-76188109