I need to monitor java application and I am using javamelody.
But the problem is, I have to get the data that javamelody has so I can show it in another screen. I know that javamelody store its rdd files in temp/javamelody directory, now I need to change the storage-directory to another path so I can get the data from that path.
How can I set the storage-directory of javamelody?
Oh I think I've found the answer
I just have to set command line or xml file in my tomcat like this
<?xml version="1.0" encoding="UTF-8" ?>
<Context docBase="pathto\appname.war" path="javamelody" reloadable="false" >
<Parameter name='javamelody.storage-directory' value='pathname' override='false'/>
</Context>
Thank you for the help :D
In web.xml, define filter javamelody with parameter storage-directory as below:
<filter>
<filter-name>javamelody</filter-name>
<filter-class>net.bull.javamelody.MonitoringFilter</filter-class>
<init-param>
<param-name>storage-directory</param-name>
<param-value>/path/to/the/storage/directory</param-value>
</init-param>
</filter>
I tested using JavaMelody version 1.60.0. For more information refer to the JavaMelody user guide.
for javamelody-spring-boot-starter
javamelody.init-parameters.storage-directory=/tmp/javamelody-${spring.application.name}
For Spring Boot
public class JavaMelodyConfiguration implements ServletContextInitializer {
#Value(value="${javamelody.storage-directory}")
String jmStorageDir;
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.addListener(new SessionListener());
servletContext.setInitParameter("javamelody.storage-directory", jmStorageDir);
}
then you can set the javamelody.storage-directory in application.properties
Related
tl;dr: Dispatching to an absolute path from a servlet fails when it (the servlet) is bound with a wildcard (/a/*) but not when bound explicitly (/b/b)
I have a Guice webapp with a servlet that dispatches traffic to an HTML file stored in WEB-INF:
#Singleton
public class MyServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/hello.html").forward(request, response);
}
}
It is configured with a GuiceServletContextListener...
public class MyApp extends GuiceServletContextListener {
#Override
protected Injector getInjector() {
return Guice.createInjector(new MyModule());
}
private static final class MyModule extends ServletModule {
#Override
protected void configureServlets() {
serve("/a/*").with(MyServlet.class);
serve("/b/b").with(MyServlet.class);
}
}
}
...and a web.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>MyApp</display-name>
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>test.MyApp</listener-class>
</listener>
</web-app>
I launch it in Tomcat and go to localhost/b/b and I see my hello.html page. However, when I go to localhost/a/a, I get a HTTP Status 404 - /WEB-INF/hello.html. This seems very strange to me as the two paths, wildcarded or not, are bound to the same servlet, as well as the HTML path being absolute and not really up for interpretation.
Is this the result of a bug, some (to me unknown) behavior I haven't accounted for, or sheer misconfiguration on my part?
Edit:
Based on some further experimentation, include seems to work as expected, which suggests to me that forward has some additional behavior I've missed. Using include will probably hold me over for now, but I'd still like to know what I'm doing wrong.
I found a GitHub issue which seems to match the problems I've encountered, meaning it's a bug in Guice itself.
The bug was originally reported in 2010 and has been treated with what seems like minor interest from contributors and none whatsoever from those in charge, so it'll probably never be fixed.
For future reference, I'm going to attempt to make do with include for now and consider switching to another framework at some point in the future.
I'm having trouble configuring the Dispatcher for Spring. What I am trying to achieve is:
Build REST WebService to receive requests
Have HTML + Ajax pages consuming the data (Therefore, I don't have Views in my Spring project)
So far I have only 2 HTML pages: Login (using j_security_check) and Main page. Both very simple. I also have a simple controller:
MainController.java
#RestController //Or #Controller and #ResponseBody, no difference, right?
public class MainController {
#RequestMapping("rest/main/data")
public String getData () {
return "{data: \"DATA HUEHUE\"}"; // Yes, I'm brazilian
}
}
And I have tried the following configuration for web.xml and dispatcher-servlet.xml:
web.xml:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
dispatcher-servlet.xml
<context:component-scan base-package="com.example.controller"/>
This doesn't work. I get the message INFO: Mapped URL path [/rest/main/data] onto handler 'mainController' but when I try to access I get No mapping found for HTTP request with URI [/myapp/rest/main/data] in DispatcherServlet with name 'dispatcher'
I also have tried:
On web.xml: <url-pattern>/</url-pattern>
On dispatcher-servlet: The same
What happened: The controller DID work but the application also tried to map my login.html and couldnt find a match so I got 404 ;-;
I'm aware of that "standard" configuration using a prefix and a sufix, but since I dont have views here I dont think that's the right approach.
I'm kinda new at Spring (as you may have noticed), so please be gentle on the answers.
Any ideas?
Thanks in advance :)
My project tree:
-project
--src
---main
----webapp
-----WEB-INF
------web.xml
------weblogic.xml
------dispatcher-servlet.xml
-----www
------main.html
-----login.html
(Login is outside www)
With the first approach if you modify the controller code to have /rest/main/data It will work.
#RestController //Or #Controller and #ResponseBody, no difference, right?
public class MainController {
#RequestMapping("/rest/main/data")
public String getData () {
return "{data: \"DATA HUEHUE\"}"; // Yes, I'm brazilian
}
}
What is happening in happening in the second approach is that since you have Spring Security configured you need to be authenticated first but for that it finds the Login.html and can not find it. This may be because of incorrect configuration.
What is needed:
There is simple web application running on Tomcat at address http://localhost:8080/.
Handler for following URL should be added:
GET http://localhost:8080/request/report/custom_report?from=2013-10-12&to=2014-10-12&download=true
which will simply write to the HttpServletResponse some data i.e. no views are involved.
What was done:
As per official Spring MVC documentation following mapping of DispatcherServlet was added to web.xml
<servlet>
<servlet-name>springDispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcher</servlet-name>
<url-pattern>/request/*</url-pattern>
<!-- PLEASE NOTE that mapping to /* is not an option -->
</servlet-mapping>
Now, because latest spring-webmvc-4.0.5.RELEASE is used I would like to add above mentioned handler with the minimum XML or Java configuration possible, so I create controller class:
package org.yura.servlet.spring;
#Controller
public class SpringRequestController {
#RequestMapping(value = "/report/custom_report",
method = GET,
produces = "application/pdf")
public void getCustomReport(
#RequestParam("from") #DateTimeFormat(pattern = "yyyy-MM-dd") final Date from,
#RequestParam("to") #DateTimeFormat(pattern = "yyyy-MM-dd") final Date to,
#RequestParam("download") final boolean download,
final HttpServletResponse response) throws IOException {
takeParamsAndWriteReportAsPdfToServletResponse(from, to, download, response.getOutputStream());
}
Then, in order for this Controller to be "picked up" by Spring I put springDispatcher-servlet.xml right next to web.xml in WEB-INF folder with following configuration (please advise if it can be simplified even more):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="org.yura.servlet.spring" />
</beans>
The Problem
With this configuration, after starting Tomcat and navigating to above mentioned URL I get Error 404.
Question 1: Please advise what is wrong with handler URLs - should I specify them as relative or what? (because as per logs, DispatcherServlet is created normally)
Question 2: Is it possible to move configuration from springDispatcher-servlet.xml to my Controller class in order not to scatter request-handling logic across multiple files.
Thanks in advance...
You haven't enabled your MVC stack. Add
<mvc:annotation-driven />
to your springDispatcher-servlet.xml (along with the appropriate namespaces).
The configuration in springDispatcher-servlet.xml is not simply request handling configuration. It can contain any bean declaration. If anything, you can move it to a Java configuration, but it should not be part of your #Controller source code.
This is my current Guice configuration:
public class MyServletModule extends ServletModule {
#Override
protected void configureServlets() {
bind(MyRest.class);
serveRegex(".+(?<!\\.(html|css|png|jpg))")
.with(HttpServletDispatcher.class);
}
}
However I want that my Rest resource is only access in form of http://127.0.0.1:8888/{hashcode_or_filename} and the only form accepted and processed (well, plus the /create method below).
Right now, I can deal with hashcode and filename properly in this path pattern.
However I am not sure how to deal the kind or scenario below, where the client is requesting path that is not mapped, which returns this in my case:
Could not find resource for relative : /examples/foo of full path:
http://127.0.0.1:8888/examples/foo
or
Could not find resource for relative : /examples/bar/foo of full
path: http://127.0.0.1:8888/examples/bar/foo
What I need is to be able to be able to handle unmapped paths so I can return a error HTML page or something and not show these error text in the browser.
Also if the request is: http://127.0.0.1:8888/ I need to forward to http://127.0.0.1:8888/index.html automatically. As right now I have to manually put the index.html in the tail.
My Resteasy resource is configure or wired with just:
#Singleton
#Path("/")
public class MyRest {
#GET
#Path({hashcode})
public Response getSomething(...){}
#POST
#Path("create")
public Response createSomething(...){}
}
Easiest way is to register filter to handle responses with error code other that 200 (OK). Or add to your web.xml something like this:
<error-page>
<error-code>404</error-code>
<location>/ErrorPage.jsp</location>
</error-page>
Also if the request is: http://127.0.0.1:8888/ I need to forward to
http://127.0.0.1:8888/index.html automatically. As right now I have to
manually put the index.html in the tail.
You can use this module http://tuckey.org/urlrewrite/
WEB-INF/web.xml
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
<init-param>
<param-name>confPath</param-name>
<param-value>/WEB-INF/urlrewrite.xml</param-value>
</init-param>
<!--...omitted...-->
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
WEB-INF/urlrewrite.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite
PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN"
"http://www.tuckey.org/res/dtds/urlrewrite4.0.dtd">
<urlrewrite>
<rule match-type="regex">
<from>^/$</from>
<to type="redirect">/index.html</to>
</rule>
</urlrewrite>
I'm embedding Jetty (version 7.4.5.v20110725) into a java application. I'm serving JSP pages in ./webapps/jsp/ using Jetty's WebAppContext, but if I visit localhost:8080/jsp/ I get Jetty's directory listing for the entire contents of ./webapps/jsp/. I've tried setting the dirAllowed parameter to false on the WebAppContext and it does not change the directory listing behavior.
Disabling the directory listing on a ResourceHandler is simply done be passing false to setDirectoriesListed, works as expected. Can someone tell me how to do this for the WebAppContext?
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.webapp.WebAppContext;
public class Test {
public static void main(String[] args) throws Exception {
Server server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setHost("127.0.0.1");
connector.setPort(8080);
server.addConnector(connector);
// Create a resource handler for static content.
ResourceHandler staticResourceHandler = new ResourceHandler();
staticResourceHandler.setResourceBase("./webapps/static/");
staticResourceHandler.setDirectoriesListed(false);
// Create context handler for static resource handler.
ContextHandler staticContextHandler = new ContextHandler();
staticContextHandler.setContextPath("/static");
staticContextHandler.setHandler(staticResourceHandler);
// Create WebAppContext for JSP files.
WebAppContext webAppContext = new WebAppContext();
webAppContext.setContextPath("/jsp");
webAppContext.setResourceBase("./webapps/jsp/");
// ??? THIS DOES NOT STOP DIR LISTING OF ./webapps/jsp/ ???
webAppContext.setInitParameter("dirAllowed", "false");
// Create a handler list to store our static and servlet context handlers.
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { staticContextHandler, webAppContext });
// Add the handlers to the server and start jetty.
server.setHandler(handlers);
server.start();
server.join();
}
}
You can set org.eclipse.jetty.servlet.Default.dirAllowed instead of dirAllowed:
webAppContext.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");
Tested for Jetty 7.4.5.v20110725, 8.1.4.v20120524, 9.0.2.v20130417 and 9.2.0.v20140526.
For anyone using web.xml, you can also disallow it there. Find the default servlet (the one with Jetty's DefaultServlet), and set the dirAllowed parameter to false:
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
<init-param>
<param-name>dirAllowed</param-name>
<param-value>false</param-value>
</init-param>
</servlet>
This works for me on Jetty v9.4.3:
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<context-param>
<param-name>org.eclipse.jetty.servlet.Default.dirAllowed</param-name>
<param-value>false</param-value>
</context-param>
</web-app>
If anyone happens across this looking for the equivalent in Jetty 6:
<bean id="webAppContext" class="org.mortbay.jetty.webapp.WebAppContext">
.
.
<property name="initParams">
<map>
<entry key="org.mortbay.jetty.servlet.Default.dirAllowed" value="false" />
</map>
</property>
I found the following page on the net which describes the same problem:
jetty-users-How-can-I-prevent-Directory-Listing-in-WebAppContext
I quote what is mentioned in one of the entries in that post as reason for the problem:
the problem is that for some reason Jetty does not merge the
webdefault.xml with user web.xml properly when embedded mode is used
and following is the code that was used to overcome the problem:
HashMap hmap = new HashMap<String, String>();
hmap.put("dirAllowed", "false");
hmap.put("redirectWelcome", "false");
hmap.put("aliases", "false");
ServletHolder []svh = wc.getServletHandler().getServlets();
if(svh != null && svh.length > 0)
{
for(int j = 0; j < svh.length; j++)
{
ServletHolder svh1 = svh[j];
if(svh1.getClassName() != null && svh1.getClassName().endsWith(DEFAULT_SERVLET))
{
svh1.setInitParameters(hmap);
}
}
}
I hope it will solve the issue for you.
The alternative solution not mentioned so far is to add the index.html file. Probably this is not a very universal solution but it fitted my needs. The added value is that this is more user friendly - a user who accidentally enters your application URL will get human readable description of your choice instead of some generic error page from Jetty.
For me this worked with embedded Jetty ver. 9.4.5.
I've put index.html next to WEB-INF directory.
In Linux with Jetty 9.2 (but i think it's the same with 9.x) to apply to all Jetty and Jetty based instances.
You can change in file /etc/jetty9/webdefault.xml:
<init-param>
<param-name>dirAllowed</param-name>
<param-value>false</param-value>
</init-param>
I've also changed:
<init-param>
<param-name>welcomeServlets</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>redirectWelcome</param-name>
<param-value>true</param-value>
</init-param>
Yet another method that works is applying this configuration to jetty-web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN"
"http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Call name="setInitParameter​">
<Arg>org.eclipse.jetty.servlet.Default.dirAllowed</Arg>
<Arg type="boolean">False</Arg>
</Call>
</Configure>