Jersey URISchemeScanner - java

A few days back, I ran into Jersey deployment issues which I posted here
Jersey Resource .class loading
We were able to use an alternative deployment mechanism by extending javax.ws.rs.core.Application and put in a temporary fix. But on researching more, I came across Jersey Scanners which can be implemented within our code. This can be made to lookup specific JARs within our project deploy structure. I was looking up the web, but could not find any specific examples of how the URISchemeScanner needs to be integrated within our code. (web.xml configuration, etc ...) Appreciate if I could be pointed in the right direction

from PackagesNamesScanner javadoc:
"Further schemes may be registered by registering an implementation of UriSchemeScanner in the META-INF/services file whose name is the the fully qualified class name of UriSchemeScanner."
See: http://jersey.java.net/nonav/apidocs/1.12/jersey/com/sun/jersey/core/spi/scanning/PackageNamesScanner.html

I am also having the problem with WAS 7. What we have done is remove the scanning Init Param itself from the web.xml and copy the Jar which contains resources in the Web-Inf Lib folder of the Web project. Then it will work. Adding J2EE dependency in the ear alone wont work.
I am using jersey 1.12 but the default scanner still have issue
Can you share the custom scanner modification you have done so that I can also try with that?

Related

Deploying war file created using jersey api

I am completely new to Java ( Beginner Java Developer). Our previous proj was created using Jersey API. I am trying to understand the project as I was not in the team of that project developers.
My Question is.. I have created the War file to that application and deployed it in tomcat. But whenever I click that project from the list, it returns an error (Requested resource is not available). I want know if I can deploy Jersey API web app in Tomcat or not? Also If I can, What may be reasons for that error? I tried everywhere and looked into all other threads but could not understand anything.
Also there is a in web.xml of our project. What is the use of this?
Please help me. Thanks a ton in advance.
I want know if I can deploy Jersey API web app in Tomcat or not?
Yes, you can. You should check your version of Tomcat, and which libraries are required to work with Jersey (usually Jersey jar itself and some common utilities). However, I didnt quite understand "was created using Jersey API". Did you use some Jersey-specific code? Because Jersey is just an implementation of some specification (namely JSR-311).
What may be reasons for that error?
Path is not specified properly, resource not initialized, etc.
Also there is a in web.xml of our project. What is the use of this?
It is a file that is responsible for the settings of 1 application. In your case, your war-archive. In web.xml you can specify the path to your war resources. Nowadays, all resources can be specified with annotations, and no need to modify web.xml exists.

Accessing WAR-packaged classpath resources from within Spring container on Weblogic 9.x

Inside web application I use some Spring scheduled-tasks (so managed standalone by Spring container). These tasks execute some business logic and require access to StringTemplate resources, which after deployment are located in WEB-INF/classes. I provide their directory as String (i.e. "some/templates") which works fine when working in exploded mode, but after switching to WAR-packaging, these resources cannot be found by ST. Project's page suggest using URL/URI (the "quagmire"), but that's a bit unclear to me. Other resources work properly, the only problem is the STGroupDir constructor.
How should I construct URL/URI/Paths arguments so that these resources could be accessed by WAR-packaged Spring-managed scheduled-tasks?
It appeared to be an issue with Weblogic 9.x creating an internal _wl_cls_gen.jar within the packaged WAR, containing all the classpath (i.e. WEB-INF/classes) resources. This results in problems with many frameworks that rely on getResource(path) methods (such as the ClassLoader one). Because of that StringTemplate could not access the group files. I fixed the problem by moving the templates out of the classpath and to WEB-INF location, then injecting the path as URL for StringTemplate to use.
I found some further information regarding this issue here and here.

Relative views in view-states within a flow that is loaded from a jar-file

I have a question regarding Spring Web Flow with JSF: How can I teach Spring Web Flow to be able to load relative views like view="pages/view.xhtml" from a jar in the classpath of a tomcat webapp? After some research via google I think, that Web Flow does not support this constellation out of the box.
Maybe some context, to help understanding my question:
- Flows are registered in multiple FlowRegistries (I solved this problem by implementing a custom implementation, which finds all flowRegistries in the Spring Context)
- Flows can reside either as file resource outside the classpath or within a jar in the classpath, i.e. file ressource flows are located somewhere in WEB-INF/conf and they are at the same position within the jar files.
- Views in the flow definitions are adressed relatively to the flow-definition-file
Now you might ask the question why we have both constellations, where the flows can reside. At the moment we are trying to extract from a big bunch of a webapp modules that contain all functionality belonging to a certain domain. The approach is to bundle all artifacts relevant there within a single project that can be built as jar and added to the webapp then.
While it is no problem to load the Spring beans for each jar without knowing where our configuration files are located, the Web Flow causes some problems.
The first problem was, that the flowRegistry is a monolith that cannot be split without doing something before hand. This problem is solved by a custom flow registry.
But now I came to a second problem: Within view states we reference the pages relatively to the flow definition, like described in the documentation:
<view-state id="some-id" view="pages/somepage.xhtml"> ... </view-state>
Now, when I enter such a view state, web flow throws an exception, which tells me that this way is not supported:
A ContextResource is required to get relative view paths within this context;
the resource was ...
Googling around brought up this possible solution:
workaround for webflows in jars
But this workaround is not working as it has a problem with my multiple flow registries.
Another option might be to not put everything into the jar, but I am not sure if that is a better idea. Likely have everything that can be loaded from classpath in the jar and the rest as pure files in a defined structure.
Any ideas? Thank you very much for your efforts and hints.
I found a slight different solution by myself after several hours of trying and debugging my application on how to accomplish the goal of the question.
first thing to change was to advance from Tomcat 6 to Tomcat 7 because of a change in the servlet API spec, that enabled me to solve my problem with slight modifications
I switched from relative referencing in view states to absolute addressing
I changed the directory structure of my jar file to fit to the newer servlet API: all file resources needed for JSF or Spring Webflow needed to be placed in META-INF/resources (see Javadoc of ServletContext look for the method getResource, it specifies what I needed)
These three steps enabled me to completely pack webflows and their resources in jar-files.

Deploying Jersey resources into a Servlet 3.0 API aware container fails miserably

(I've accidentally deleted the gist that I'm referring to in this question; sorry for the inconvenience.)
The Question
I'm trying to use the Servlet 3.0 API to deploy Jersey root resources (those annotated with the #Path annotation) following the Jersey's user guide.
I've created a gist at GitHub containing two classes: Foo.java which is a subclass of Application that exposes Bar.java (the resource class) through its getClasses() method. (There is a pom.xml too, so anyone can try this out for herself/himself easily.)
However, when I try to deploy the packaged war to a Jetty 8.0.x instance I get the output available here at pastebin.
Foo.java gets called, its getClasses() method gets called too while Bar.java is never invoked.
I can reach Jetty's welcome page at http://localhost:8080/, however I neither can reach http://localhost:8080/foo or http://localhost:8080/foo/bar. The latter two results in the following error:
Not Found ERROR
custom 404 page
What could be the problem? Am I doing something wrong here?
The Answer
Given the WAR I've used (test-0.0.1-SNAPSHOT.war) my application path became http://localhost:8080/test-0.0.1-SNAPSHOT/foo/bar instead of http://localhost:8080/foo/bar. See what I did there? Good. Engrave this in your mind people or lose 3-to-5 precious hours of your life!
OK. I've solved the problem.
My application's path isn't at http://localhost:8080/foo/bar but at http://localhost:8080/<the name of my war file>foo/bar. So given the pom.xml I've posted it becomes http://localhost:8080/test-0.0.1-SNAPSHOT/foo/bar.
I hate WAR files.
You've got one call with #Path, while the other have #ApplicationPath with NO #Path on the method.
As you can here,
JAX-RS API (from version 1.1.4) introduced a specific annotation ( #javax.ws.rs.ApplicationPath ), that provides an alternative to web.xml configuration:
But you'll need at least a #Path on the called method. However, the simplest thing is probably to start with a classic old web.xml, then using #Path on Resources. You'll get plenty of exemples in the web, while #ApplicationPath is not common.
While this wasn't your problem, if you're trying to deploy in Jetty 8 in Cargo, you would likely have hit this bug: http://jira.codehaus.org/browse/CARGO-1133

getResourceAsStream not loading resource in webapp

I have a web application that uses a library which resides in TOMCAT_HOME/common/lib. This library looks for a properties file at the root of the classpath (in a class called ApplicationConfig):
ApplicationConfig.class.getResourceAsStream("/hv-application.properties");
My Tomcat web application contains this properties file. It is in WEB-INF/classes, which is the root of the classpath right? However, at runtime, when it tries to load the properties file, it throws an exception because it can't find it (getResourceAsStream returns null).
Everything works fine if my application is a simple, standalone Java application. Does Tomcat cause the getResourceAsStream method to act differently? I know there's a lot of similar questions out there, but none of them have helped unfortunately. Thanks.
Try Thread.currentThread().getContextClassLoader().getResourceAsStream("/hv-application.properties") instead.
This looks like it might be related to how Tomcat classloaders work. If you have something in one class loader (your config file in the webapp classloader) that's used by something in another (the jar in common/lib), the result could be a big headache.
This document explains how Tomcat delegates to class loaders. If possible, could you try one of the following:
Move the jar file in common/lib into your web application (WEB-INF/lib). This is not always possible I know, but sometimes jars (e.g. log4j) can coexist peacefully across classloaders (*).
Move your configuration file into common/classes. This is effectively the same thing (puts the configuration item into the same classloader as the jar that needs it). Again, this is not ideal, but if you have control over your environment, it would work.
Either way, having resources in different classloaders can be a pain. I hope this helps.
(*) log4j has the -log4j.ignoreTCL option which makes this possible though
The Tomcat security manager generally won't let you access webapp classes and resources from libraries in the Tomcat root libraries. This is meant to give separation between the web applications running in a container.
You should be able to get around this by updating the security policy, but it's generally better to not put your libs into the Tomcat container, which I assume you are doing.
I'm expanding Olivier comment as a response (thank you for the lead).
The problem seems to be the leading slash (/) in the resource path.
In Tomcat 8 the WebAppClassloader correctly resolves the path with and without the leading slash. Both .getResourceAsStream("/org/pakopa/app/config.properties"); and .getResourceAsStream("org/pakopa/app/config.properties"); returns an InputStream.
In Tomcat 7 (And I assume previous versions too) .getResourceAsStream("/org/pakopa/app/config.properties"); is not resolved and returns null but .getResourceAsStream("org/pakopa/app/config.properties"); is correctly resolved.

Categories