Using Jetty's proxy in standalone Jetty application - proxy

I'm investigating using Jetty 9 as a proxy, using standalone Jetty, not embedded Jetty. I've looked for help in many places:
Most of these are related to embedded Jetty:
How to create Proxy Server using jetty8?
Jetty ProxyServlet with SSL support
This question is along the same lines:
Can stand-alone Jetty be used as a reverse proxy (without Apache mod-proxy)
...but the only answer is a link to a page that covers some parameters for the proxy, but no examples or other helpful hints.
On to the question...
I've created an extension to Jetty's ProxyServlet, which overrides the rewriteURI() method to actually change the request to a different URL. This custom proxy works when running Jetty embedded, but when I use a web.xml file and the jetty-maven-plugin to create a war to deploy, it no longer works.
When I make a request, I can debug the application and see that it gets into the rewriteURI() method, it then calls Jetty's ProxyServlet's service() method, which runs to completion, but then nothing happens. The page remains blank, and eventually ProxyServlet's onResponseFailure() is called with a TimeoutException, "Total timeout elapsed". Dev tools shows the request receiving a 504 Gateway Timeout.
It seems as though something is missing in how things are connected, but I can't tell what it might be. Any help would be greatly appreciated. I've included web.xml and the custom proxy (ProxyServletExtension) below.
web.xml
<servlet>
<servlet-name>proxy</servlet-name>
<servlet-class>org.example.ProxyServletExtension</servlet-class>
<init-param>
<param-name>maxThreads</param-name>
<param-value>1</param-value>
</init-param>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>proxy</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
ProxyServletExtension.java
...
import org.eclipse.jetty.proxy.ProxyServlet;
...
public class ProxyServletExtension extends ProxyServlet {
#Override
protected URI rewriteURI(HttpServletRequest request) {
// Forward all requests to another port on this machine
String uri = "http://localhost:8060";
// Take the current path and append it to the new url
String path = request.getRequestURI();
uri += path;
// Add query params
String query = request.getQueryString();
if (query != null && query.length() > 0) {
uri += "?" + query;
}
return URI.create(uri).normalize();
}
}

I found the hints I needed to solve this with jetty transparent proxy always returns 403 forbidden. The question didn't exactly pertain to my question, but the code snippet provided showed me what I needed in the <servlet> in web.xml.
Updated web.xml
<servlet>
<servlet-name>proxy</servlet-name>
<servlet-class>org.example.ProxyServletExtension$Transparent</servlet-class>
<init-param>
<param-name>maxThreads</param-name>
<param-value>1</param-value>
</init-param>
<init-param>
<param-name>proxyTo</param-name>
<param-value>http://localhost:8060</param-value>
</init-param>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>proxy</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Required changes
Set the <servlet-class> to ProxyServletExtension$Transparent, previously I wasn't using a trasparent proxy.
Use an <init-param> of proxyTo using the address you would like to proxy the requests to. This also means that the ProxyServletExtension.java class above (in the question) is completely unnecessary.
Also, it is worth mentioning that there is a prefix <init-param> as well, which can be used to remove part of the incoming request before proxying to the proxied request.

Related

com.sun.jersey.api.container.ContainerException : The ResourceConfig instance does not contain any root resource classes [duplicate]

What's going wrong here?
The ResourceConfig instance does not contain any root resource classes.
Dec 10, 2010 10:21:24 AM com.sun.jersey.spi.spring.container.servlet.SpringServlet initiate
SEVERE: Exception occurred when intialization
com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes.
at com.sun.jersey.server.impl.application.RootResourceUriRules.<init>(RootResourceUriRules.java:103)
at com.sun.jersey.server.impl.application.WebApplicationImpl._initiate(WebApplicationImpl.java:1182)
at com.sun.jersey.server.impl.application.WebApplicationImpl.access$600(WebApplicationImpl.java:161)
at com.sun.jersey.server.impl.application.WebApplicationImpl$12.f(WebApplicationImpl.java:698)
at com.sun.jersey.server.impl.application.WebApplicationImpl$12.f(WebApplicationImpl.java:695)
at com.sun.jersey.spi.inject.Errors.processWithErrors(Errors.java:197)
at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:695)
at com.sun.jersey.spi.spring.container.servlet.SpringServlet.initiate(SpringServlet.java:117)
Filter:
<filter>
<filter-name>JerseyFilter</filter-name>
<filter-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</filter-class>
<init-param>
<param-name>com.sun.jersey.config.feature.Redirect</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.JSPTemplatesBasePath</param-name>
<param-value>/views/</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.WebPageContentRegex</param-name>
<param-value>/(images|css|jsp)/.*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>JerseyFilter</filter-name>
<url-pattern>/myresource/*</url-pattern>
</filter-mapping>
Code:
#Path ("/admin")
public class AdminUiResource {
#GET
#Produces ("text/html")
#Path ("/singup")
public Viewable getSignUp () {
return new Viewable("/public/signup", "Test");
}
}
Have you tried adding
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>my.package.name</param-value>
</init-param>
to your SpringServlet definition? Obviously replace my.package.name with the package that AdminUiResource is in and make sure it is in the classpath.
I am new to Jersey - I had the same issue, But when I removed the "/" and just used the #path("admin") it worked.
#Path("admin")
public class AdminUiResource { ... }
YOU NEED TO ADD YOUR PACKAGE NAME AT
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>your.package.name</param-value>
</init-param>
ALSO ONE SILLY THING I HAVE NOTICED,
I Need to refresh my project after MAVEN BUILD else it show me same error.Please comment If you know reason why we need to refresh project?
This means, it couldn't find any class which can be executed as jersey RESTful web service.
Check:
Whether 'com.sun.jersey.config.property.packages' is missing in your
web.xml.
Whether value for 'com.sun.jersey.config.property.packages'
param is missing or invalid (the mentioned package doesn't exists). It should be a package where you have put your POJO classes which runs as jersey services.
Whether there exists at least one POJO class, which has a method annotated with #Path attribute.
Your resource package should contain at least one pojo which is either annotated with #Path or have at least one method annotated with #Path or a request method designator, such as #GET, #PUT, #POST, or #DELETE. Resource methods are methods of a resource class annotated with a request method designator. This resolved my issue...
I ran across this problem with JBOSS EAP 6.1. I was able to deploy my code through eclipse to the JBOSS server but once I attempted to deploy the file as a WAR file to JBOSS I started getting this error.
The solution was configuring the web.xml to work properly with JBOSS by allowing the two to work together.
The following two lines were commented out in web.xml to allow JBOSS to do it's own configurations
<!--
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.your.package</param-value>
</init-param> -->
And then add the following context params after
<context-param>
<param-name>resteasy.scan</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>resteasy.scan.resources</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>resteasy.scan.providers</param-name>
<param-value>false</param-value>
</context-param>
Basically I corrected it like below and everything worked fine.
<servlet>
<servlet-name >MyWebApplication</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.feature.Redirect</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.JSPTemplatesBasePath</param-name>
<param-value>/views/</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.WebPageContentRegex</param-name>
<param-value>/(images|css|jsp)/.*</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>MyWebApplication</servlet-name>
<url-pattern>/myapp/*</url-pattern>
</servlet-mapping>
I am getting this exception, because of a missing ResourseConfig in Web.xml.
Add:
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>/* Name of Package where your service class exists */</param-value>
</init-param>
Service class means: class which contains services like: #Path("/orders")
I had the same issue with trying to run the webapp from an eclipse project. As soon I copied the .class files to /WEB-INF/classes it worked perfectly.
I had the same issue, testing a bunch of different examples, and tried all the possible solutions. What finally got it working for me was when I added a #Path("") over the class line, I had left that out.
Had the same issue and found out it was a problem with the way I deployed my source code. As the error message says: "...does not contain any root resource classes". So it couldn't find any resource classes in the configured package. I just deployed the classes wrong - that's why it didn't pick it up.
I forgot to deploy my class files in the /WEB-INF/classes directory of the WAR - initially I just had it directly in the root of the WAR file. So when it looked for resource classes it didn't find them - because they existed in a different (wrong) location.
Same issue - web.xml looked like this:
<servlet>
<servlet-name>JerseyServlet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.mystuff.web.JerseyApplication</param-value>
</init-param>
...
Providing a custom application overrides any XML configured auto detection of classes. You need to implement the right methods to write your own code to wire up the classes. See the javadocs.
Another possible cause of this error is that you have forgotten to add the libraries that are already in the /WEBINF/lib folder to the build path (e.g. when importing a .war-file and not checking the libraries when asked in the wizard). Just happened to me.
It happened to me when I deployed my main.jar, without checking the add directory entries box in the export jar menu in Eclipse.
Well, it's a little late to reply. I have faced the same problem and my Google searches were in vain. However, I managed to find what the problem was. There might be many reasons for getting this error but I got the error due to the following and I wanted to share this with my fellow developers.
I previously used Jersey 1.3 and I was getting this error. But when I upgraded the jars to the latest version of Jersey, this issue was resolved.
Another instance in which I got this error was when I was trying to deploy my service into JBoss by building a war file. I made the mistake of including the Java files in the .war instead of java classes.
I had to add a trailing forward slash to the end of #path
#Path ("/admin/")
Ok... For me work fine just only assigning the "servlet-class" to com.sum.jersey.spi.container.servlet.ServletContainer, I am using IDE (Eclipse Mars)
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/frontend/*</url-pattern>
</servlet-mapping>
but for some reason I had to reboot my computer in order to work in my localhost. If still not work? You have to add in your web.xml this code in between "servlet" tag.
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>the.package.name</param-value>
</init-param>
"the.package.name" is the package name where you have your classes. If you are using IDE, refresh the project and run again in Tomcat. still not work? reboot your computer and will work.
Another thing to check is a combination of previous entries
You can have in your web.xml file this:
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.acme.rest</param-value>
</init-param>
and you can have
<context-param>
<param-name>resteasy.scan</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>resteasy.scan.providers</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>resteasy.scan.resources</param-name>
<param-value>false</param-value>
</context-param>
but you cannot have both or you get this sort of error. The fix in this case would be to comment out one or the other (probably the first code snippet would be commented out)
yes adding the init param for com.sun.jersey.config.property.packages fixed this issue for me.
was merging a jersey rest services into maven based spring application and got this error.
I also got this kind of error, please take care of the configurations in xml.
I wrote
com.sun.jersey.comfig.property.packages
Instead of
com.sun.jersey.config.property.packages
After correction it's working.
that issue is because jersey can't find a dependecy package for your rest
service declarated
check your project package distribution and assert that is equals to your web.xml param value
Probably too late but this is how I resolved this error.
If this solution is not working,
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>/* Name of Package where your service class exists */</param-value>
</init-param>
In eclipse:
RightClick on your Project Or Select Project and press Alt + Enter On the left-hand side of the opened window find Java Build Path
Select Libraries from the right tab panel: If there is anything which is corrupted or showing cross mark on top of the jars, remove and add the same jar again
Apply and Close
Rebuild your project
In my case I have added the jars twice in build path after importing from war.
It worked fine after removing the extra jars which was showing error deployment descriptor error pages
adding
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>service.package.name</param-value>
</init-param>
Also came accross this problem, twice for different reasons. The first time I forgot to include
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>my.package.name</param-value>
</init-param>
as described in previous comments, and once I did that, it started working.
Yet... another day I started Eclipse, expecting to continue where I left off, and instead of having my program working, it showed the very same error once again. I started checking if I accidentally had made some changes and saved corrupted file, but could find no such error and the file looked exactly like examples I have, all in order. Since it worked the day before, after some initial searching, I thought, well, maybe it's a Eclipse, or Tomcat glitch or something, so let's just try to make some changes and see if it reacts. So, I did a space + backspace in web.xml file, just to fool Eclipse that the file is changed, and saved it then. The next step was restarting Tomcat server (from Eclipse IDE) and voila, it works again!
Maybe someone with broader experience could explain what the problem really was behind all of this?
Main cause of this Exception is:
You have not given the proper package name where you using the #Path or forgot to configure in web.xml / Configuration file(Rest API Class File package Name, Your Class Package Name)
Check this Configuration inside <init-param>

***Unable to Connect servlet methods in wicket through objectstream.***

I want to connect servlet using urlconnection in wicket-spring integration, but when i try to hit the url its redirecting to webapplication page, So can anyone tell me how to connect servlet methods by using filters or any other way, so that i can directly hit dopost or doget methods.
The question is not very clear, so I'll try to guess. I suppose that you have a Wicket filter that intercepts and handles all the requests. Also you have some servlet, and you want requests to that servlet to not be intercepted by Wicket filter.
If this is what you want, here is what you can do to achieve this.
Let's say you have Wicket filter mapped to / and the servlet mapped to /my-service. Then you could tell Wicket filter to ignore requests to /my-service url:
<filter>
<filter-name>wicket.filter</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>... some application class name ...</param-value>
</init-param>
<init-param>
<param-name>ignorePaths</param-name>
<param-value>/my-service</param-value>
</init-param>
</filter>
If you want several paths to be ignored, you can separate them with commas like this:
<init-param>
<param-name>ignorePaths</param-name>
<param-value>/my-service,/my-other-service</param-value>
</init-param>
With this configuration, Wicket will ignore any requests under /my-service (that is, /my-service, /my-service/blabla and so on) and any request under /my-other-service.

Spring MVC DispatcherServlet mapping / vs /*

<servlet>
<servlet-name>springmvcdemo</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvcdemo</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
vs
<servlet>
<servlet-name>springmvcdemo</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvcdemo</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
I know there are duplicated questions but i'm still confused. My understanding is that when using /* , every request will go through this servlet (It means all .jsp, .html,etc will end up in this ). / will make this servlet the default servlet ( if there are exact URL installed..., return ) But it seem to me that when using / every request all still go through The DispatcherServlet no matter what. I can't open any .jsp file directly. Can someone explain to me more about this?
As per the Servlet specification, mapping for "/" means default servlet meaning if there is no explicit servlet matching the request, then this default servlet would be serving the request. For e.g., there is a servlet named "default" defined in Tomcat server common configuration web.xml which is inherited by all applications. This servlet serves the static contents like css,images etc which are typically not mapped in applications web.xml. Similarly there is a special Servlet which handles requests for jsp files ( all request ending with *.jsp as naturally these will be needed to be compiled to Servlets which would then process the request). So if you override the default servlet to be any other servlet in the application web.xml, then all requests not handled by any other servlet goes to this servlet and if this Servlet is not capable to serving request, it will not work.
If you declare Spring dispatcher servlet as the default Servlet, then you will not be able to serve static contents from container provided Servlet. Instead there is a special handler provided which can load static resources from configurable path pattern from directory / classpath. You need to use <mvc:resources/> tag for this feature. However if you still want to use container provided Servlet for serving resource you would need to use
<mvc:default-servlet-handler/> in the spring configuration. You can read more about this approach and its prons/cons here - section 15.12.4

Spring WS : Start Endpoint at startup

I'm using Spring WS to create WebService following by the link here
http://briansjavablog.blogspot.com/2013/01/spring-web-services-tutorial.html
And dynamic wsdl following by the setting here in web.xml
<servlet>
<servlet-name>webservices</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
<init-param>
<param-name>transformWsdlLocations</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
I would like to ask is that possible to create Endpoint bean on startup time rather than waiting client to call on the endpoint url ?
Even if I set annotation #Lazy(false), Endpoint bean will be initialised only when client call to the web service address which I believe it's the normal behaviour. I'll use workaround solution by putting "curl" script to call url on deployment to make sure that every beans are initialised before making any request

How to get a trivial case of Spring MVC view (JSP) resolving to work?

My app uses Spring MVC (latest; 3.2.2) to create a RESTful API returning JSON, and so far I haven't needed a view layer at all. But now, besides the API, I need a simple utility page (plain dynamic HTML) and wanted to use JSP for that.
I want requests to http://localhost:8080/foo/<id> to go through a controller (Java) and end up in a JSP. Should be simple, right? But I'm getting 404; something is not right in resolving the view.
HTTP ERROR 404
Problem accessing /jsp/foo.jsp. Reason:
Not Found
Controller:
#RequestMapping(value = "/foo/{id}")
public String testing(#PathVariable String id, ModelMap model) {
model.addAttribute("id", id);
return "foo";
}
Defining controllers and mapping requests works; this method gets called just fine.
Spring config:
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/jsp/" p:suffix=".jsp"/>
The problem is probably here. I've experimented with slightly different prefixes and putting the JSPs under WEB-INF, as well as stuff like <mvc:view-controller path="/*" /> but no luck yet.
(Do I even need to specify InternalResourceViewResolver, or should default view resolvers take care of this?)
JSP files. Under src/main/webapp/jsp (the project uses Maven conventions) I obviously have the JSPs.
Is there something wrong with this location?
web.xml:
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
I have browsed through Spring MVC documentation, but my problem is probably too trivial and obvious to easily find help there. :-P
Can anyone enlighten me on what I'm doing wrong?
I think what you need to do is changing
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
to
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
/* won't match if there is another folder in the path, like /jsp/foo.jsp. On the other hand / will match everything.

Resources