jboss deployment issue - can not visit servlet - servlets

I am trying to write a simple web application and deploy on jboss EAP 6. The application is named "webapp" and I was able to build and deploy it to jboss. The context root is /webapp.
I was able to then visit localhost:8080/webapp and it returns a "Hello World" printed from the defaulted index.jsp that was generated by eclipse at /src/main/webapp.
However, when I tried to actually visit the servlet at localhost:8080/webapp/sessionsetup I got the following error:
JBWEB000065: HTTP Status 404 - /webapp/sessionsetup
JBWEB000309: type JBWEB000067: Status report
JBWEB000068: message /webapp/sessionsetup
JBWEB000069: description JBWEB000124: The requested resource is not available.
Below is my simple code for the servlet:
#WebServlet("/sessionsetup")
public class SessionSetup extends HttpServlet{
private static final Logger log = LoggerFactory.getLogger(SessionSetup.class);
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
log.info(this.toString());
log.info("Do get method is called");
response.setContentType("text/xml");
PrintWriter printer = response.getWriter();
printer.println("<html>");
printer.println("<head>" + "</head>");
printer.println("<body>");
printer.println("<h1>" + "Welcome! You are in session setup" + "</h1>");
printer.println("</body>");
printer.println("</html>");
printer.close();
}
}
Could anyone comment on where I might miss something? Is there a way to find some log information no this error? I tried to look for server.log at /standalone/log but couldn't find anything.

There can be 2 reasons
(1) you can configure your standalone.xml in jboss server
virtual-server name="default-host" enable-welcome-root="false">
use false instead of true in enable-welcome-root
(2)
you have not done mapping of controller properly

Problem resolved. It appears to be an issue with the web.xml - once this is removed, the servlet is available.

The actual problem should be the way how it was deployed(Run time name) in the jboss.
So if you try to access the application on that it should works.
Runtime Name: Name by which the deployment should be known within a server's runtime. This would be equivalent to the file name of a deployment file, and would form the basis for such things as default Java Enterprise Edition application and module names. This would typically be the same as 'name', but in some cases users may wish to have two deployments with the same 'runtime-name' (e.g. two versions of "foo.war") both available in the deployment content repository, in which case the deployments would need to have distinct 'name' values but would have the same 'runtime-name'.

This is just my experience about how this problem might happen and the way I have solved issue.
This problems happens in the absence of war file. When I deployed
hawtio
to monitoring jboss which it needs
jolokia
so I just download and deployed manually the .war file into my jboss then problem has been solved.

I think you have to add WEB-INF/jboss-web.xml file in which you have set the context root
<jboss-web>
<context-root>contextroot</context-root>
</jboss-web>

Clean Server to solve this problem in many cases work..

Related

Disable access to a Servlet

I'm developing a WebApp using JavaEE and I use a servlet to test some stuff.
Currently, my WebApp is set as when I go to my local url localhost:8080/myApp/test , I can run my test Servlet.
My plan is to deploy my project to a Web and I want to disable the Servlet, but not delete it. I mean, if in the future I visit my remote server via URL www.myNewWeb.com/test , I would like it throws an error od do nothing.
How could I do that?
There are many possible options here:
Option 1
Remove the mapping (annotation #WebServlet or url mapping entry in web.xml). In this case, any attempt to call this servlet will end with an error generated by the JEE container of your choice. It will try to map the servlet to URL, will obviously fail and throw an exception
The obvious drawback of this method is that you need to change the deployment configuration and if you'll want to run the same artifact in another envrironment where this servlet should work you won't be able to do so.
Option 2
Create some kind of configuration, load this configuration along with your application.
In the doGet (just for the sake of example) method do something like this:
public void doGet(request, response) {
if(config.isTestServletEnabled()) { // this is where the data gets read from configuration that I've talked about before
// do your regular processing here
}
else {
// this will happen when the servlet should not be activated
// throw an exception, return HTTP error code of your choice, etc
}
}
This way doesn't have a drawback of the first method that I've explained above, however involves some code to be written.

ASP.NET Web API v2 and logging all errors/exceptions with ELMAH

Despite spending hours searching the net I couldn't find a solution to this problem. Being a noob to Web API v2 this is probably a really easy question for someone with more experience.
I have a clean MVC project updated to use Web API v2. I've installed a number of ELMAH packages via Nuget.
When working with the normal Home controller in MVC if I put an invalid page e.g. /Home/test it would generate a 404. Elmah in turn captures this and I know just from the logs what pages might be broken etc.
I want to transfer this level of logging over to the API controller. The logging does work, but I have to throw an exception to the controller to get something logged in Elmah.
I'm guessing that things like 404/415 errors are classed as 'handled' exceptions, but I'm only getting un-handled exceptions logged.
At any rate what I want is for ANY errors on the API controller to be logged. This way I can monitor how the API is being used and any errors caused by calling clients. Errors might be 404s, 415 for unsupported data types and so on. That way if there are any problems with posted data from a client I can easily see the response that would have been passed back.
Thanks in advance!
WebApi.config:
Public static void Register(HttpConfiguration config)
{
...
config.filters.add(new Elmah.Contrib.WebApi.ElmahHandleErrorApiAttribute());
}
Filter.config:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new Elmah.Contrib.Mvc.ElmahHandleErrorAttribute());
filters.Add(new HandleErrorAttribute();
}
It turns out that 404 errors are treated a bit differently in Web API, they bypass the usual request pipeline and are sent directly to the browser before ELMAH knows anything about them.
So in order to log 404 errors with ELMAH you need to add a 'catch all' route as the last route in your WebApiConfig to log the errors manually.
I've just updated the post and included a working example solution - http://jasonwatmore.com/post/2014/05/03/Getting-ELMAH-to-catch-ALL-unhandled-exceptions-in-Web-API-21.aspx
You need to register an exception logger with Web API as well. Check out this awesome post: http://www.jasonwatmore.com/post/2014/05/03/Getting-ELMAH-to-catch-ALL-unhandled-exceptions-in-Web-API-21.aspx

SpringMVC session managament

I have a simple SpringMVC v3.2.2 controller that does the following:
#RequestMapping(value = { "/login" }, method = RequestMethod.GET)
public String login(WebRequest request) {
request.setAttribute("myattr", "myvalue", SCOPE_SESSION);
}
I'm using the WebRequest object in order to save attributes in the session scope. The SCOPE_SESSION is an integer stating that I want to use it in the session scope. More info on the API is here:
WebRequest API
I assume that it means that I'm adding some attribute that will be saved in the session scope. Session, I assume, will be deleted when the server restarts, during my tests, because I don't want to have any session persisted locally. Unless some default configuration keeps it persisted.
For some reason, the session doesn't get deleted even after tomcat restart(I'm using Tomcat V7, default configuration), meaning that it is persisted for some reason. Tried to find more documentation explaining how to disable it, but could not.
What Am I missing ? if the attribute is saved in the session scope, as the API states, should it get deleted if I restart the Tomcat Server ?
Thanks in advance,
Elad.
I have edited the original question, which was not so clear. Sorry.
Problem solved. I totally missed that the session management is controlled by Tomcat.
The solution was to edit the Tomcat 7 context.xml configuration file and make sure it has the following element :
This disables the session persistence for good. Didn't really think that this is how it works by default. Thank you anyway.

Spring Security with HTTPS on CloudFoundry

I tried to access my application on CloudFoundry with the following configuration in the spring security xml
<intercept-url pattern="/signup*" access="permitAll" requires-channel="https" />
but it gives me error This webpage has a redirect loop
However when I changed it to requires-channel="http" I can see my page normally. In both cases I used https on my application. Is this the expected behavior ?
First of all, taking a step back, this (https://johnpfield.wordpress.com/2014/09/10/configuring-ssltls-for-cloud-foundry/) provides excellent context for the nature of the problem.
The key paragraph being
“The threat model here is that the entry point to the cloud is a high availability, secured proxy server.  Once the traffic traverses that perimeter, it is on a trusted subnet.  In fact, the actual  IP address and port number where the Tomcat application server are running are not visible from outside of the cloud. The only way to get an HTTP request to that port is to go via the secure proxy. This pattern is a well established best practice amongst security architecture practitioners.”
Therefore, we may not want or need SSL all the way down, but read on to see how to avoid the https redirect issue when using Spring Security deployed on Cloud Foundry.
You will have a load balancer, HAProxy or some kind of proxy terminating SSL at the boundary of your Cloud Foundry installation. As a convention, whatever you are using should be configured to set X-Forwarded-For and X-Forwarded-Proto headers. The request header “X-Forwarded-Proto" contains the value http or https depending on the original request and you need to use this header parameter for your security decisions further down the stack.
The cleanest way to do this is at the container level, so that Spring Security behaves the same independent of deployment container. Some typical options to configure this are as follows
1) Tomcat
Tomcat should be configured with a RemoteIPValve as described nicely here
The good news is that the Java buildpack for Cloud Foundry already does this for you as seen here
2) Spring Boot (Embedded Tomcat)
Because Tomcat is embedded, the Tomcat config in the Java buildpack will not be activated (see the buildpack Detection Criterion), and therefore some internal Spring Boot configuration is required. Luckily, it’s pretty trivial to configure as you would expect with Spring Boot and you can switch on Tomcat’s RemoteIPValve as explained here by simply defining
server.tomcat.remote_ip_header=x-forwarded-for
server.tomcat.protocol_header=x-forwarded-proto
Both approaches lead to the same outcome of the Tomcat valve overriding the ServletRequest.isSecure() behaviour so that the application has no knowledge of the usage of any proxying. Note that the valve will only be used when the “X-Forwarded-Proto" header is set.
Alternatively, if you really want to go low-level you can dig into the guts of Spring Security, as demonstrated here. As part of that effort, there are some useful findings on how to make the “X-Forwarded-Proto" header available via the Servlet API for other containers (WebLogic, JBoss, Jetty, Glassfish) shared on the comments of https://github.com/BroadleafCommerce/BroadleafCommerce/issues/424
As an additional note, CloudFlare can also act as the SSL-terminating reverse proxy (this is the recommended approach via PWS as discussed here) and it does indeed forward the relevant headers.
References
https://stackoverflow.com/a/28300485/752167
http://experts.hybris.com/answers/33612/view.html
https://github.com/cloudfoundry/java-buildpack/commit/540633bc932299ef4335fde16d4069349c66062e
https://support.run.pivotal.io/entries/24898367-Spring-security-with-https
http://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-servlet-containers.html#howto-use-tomcat-behind-a-proxy-server
I have the same issue when I tried to secure my pages with HTTPS using Spring Security.
From the discussion on CloudFoundry Support, seems they "terminate SSL connections at the router". See "Is it possible to visit my application via SSL (HTTPS)?".
And after more than a year, no further information I can find regarding this issue.
In case it's still useful ... I found this post gave the clue to solve something similar to this.
The problem was the org.springframework.security.web.access.channel.SecureChannelProcessor bean was using ServletRequest.isSecure() to decide whether to accept the connection or redirect, which was getting confused inside the cloud.
The following override to that bean seemed to do the job under BlueMix - not sure if the $WSSC request header will apply to all environments.
#Component
public class ChannelProcessorsPostProcessor implements BeanPostProcessor {
#Override
public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException {
if (bean instanceof SecureChannelProcessor) {
final SecureChannelProcessor scp = (SecureChannelProcessor) bean;
return new ChannelProcessor() {
#Override
public void decide(FilterInvocation invocation,
Collection<ConfigAttribute> config) throws IOException,
ServletException {
HttpServletRequest httpRequest = invocation.getHttpRequest();
// Running under BlueMix (CloudFoundry in general?), the
// invocation.getHttpRequest().isSecure() in SecureChannelProcessor
// was always returning false
if ("https".equals(httpRequest.getHeader("$WSSC"))) {
return;
}
scp.decide(invocation, config);
}
#Override
public boolean supports(ConfigAttribute attribute) {
return scp.supports(attribute);
}
};
}
return bean;
}
#Override
public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException {
return bean;
}
}

How do I get the host domain name in ASP .NET without using HttpContext.Current.Request?

I've got an ASP .Net application running on IIS7. I'm using the current url that the site is running under to set some static properties on a class in my application. To do this, I'm getting the domain name using this (insde the class's static constructor):
var host = HttpContext.Current.Request.Url.Host;
And it works fine on my dev machine (windows XP / Cassini). However, when I deploy to IIS7, I get an exception: "Request is not available in this context".
I'm guessing this is because I'm using this code in the static constructor of an object, which is getting executed in IIS before any requests come in; and Cassini doesn't trigger the static constructor until a request happens. Now, I didn't originally like the idea of pulling the domain name from the Request for this very reason, but it was the only place I found it =)
So, does anyone know of another place that I can get the host domain name? I'm assuming that ASP .Net has got to be aware of it at some level independent of HttpRequests, I just don't know how to access it.
The reason that the domain is in the request is...that's what's being asked for. For example these are a few stackexchange sites from http://www.stackexchangesites.com/:
http://community.ecoanswers.com
http://www.appqanda.com
http://www.irosetta.com/
If you ping them, you'll see they all point to the same IP/Web Server and be served by the same app (or multiple apps in this case, but the example holds if it was one big one)...but the application doesn't know which one until a host header comes in with the request asking the server for that site. Each request may be to a different domain...so the application doesn't know it.
If however it doesn't change, you could store it as an appSetting in the web.config.
Use global.asax or write a HttpModule and subscribe to start request events. You will have the request passed into your event handler.
Use this instead:
HttpRuntime.AppDomainAppVirtualPath
Or if you want the physical path:
HttpRuntime.AppDomainAppPath
For further reading:
http://weblogs.asp.net/reganschroder/archive/2008/07/25/iis7-integrated-mode-request-is-not-available-in-this-context-exception-in-application-start.aspx

Resources