I am working on a Java Portlet (extending GenericPortlet), using JBoss 7.02 and LifeRay Portal 6.1.0 GA1. This is one of the bundles that can be downloaded from LifeRay's release archive.
During deployment, when the init() method is called, getRequestDispatcher() returns null. Below is the exact error message:
09:22:15,972 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/my-portlet-name]] (MSC service thread 1-15) Error during mapping: java.lang.NullPointerException
Below is a snippet from my init() method:
PortletConfig config = getPortletConfig();
PortletContext context = getPortletContext();
PortletRequestDispatcher normalView = context.getRequestDispatcher("/portlet.jsp");
As a temporary workaround, I have moved all getRequestDispatcher() calls to doView() where it executes without problem. I do not understand why getRequestDispatcher() can locate portlet.jsp when called during doView, but not when its called during init()
Am I missing a preceding call of some other method that would resolve this? Is this a known issue?
Thanks for any help.
Getting the request dispatcher in the doView is the only place I've seen it done. I would imagine that it returns null during init because there is no actual request to dispatch.
Typically the init method is used for time-expensive operations that you don't want to incur for each request. This might be something like reading data from a file, or creating a reusable SQL connection.
You should also keep in mind that you should keep any portlet state thread safe. Don't create class or object variables that can only be used for one request at a time. The portlet methods are not inhererently thread safe, so you need to make sure that whatever variables a request is interacting with won't be manipulated by another request that is executing concurrently.
I'm not familiar with Portlets, but the answer should be the same as for Servlets.
The init() method is called exactly once, when your application is initially deployed. There is no active request (no one is asking for anything) or response (no one is going to read what the output is). Therefore, it is very reasonable forgetRequestDispatcher() to return null. In doView(), when you're handling a request and response, it makes sense to ask another resource to generate part (or all) of the response.
To address your question directly, getRequestDispatcher() has no problem locating portlet.jsp from init(); it's the request that's missing. (Where do you expect to see the result of portlet.jsp, anyway?)
If you do want to print some output during initialization, you can try logging it to a file, if your application is set up for that. Or, you can display data on System.out, if you know where the container's console is. (I use this second option quite often with servlets.)
Related
I want to download file after query but the time is too long, so my company said I should let the process in background.
For that I create thread when user call method, it will generate file and send to email of customer.
But the problem is about my thread, I also test function for sendemaildownload (it also includes the function which I use to query), I'm quite sure this problem from the way I create the thread.
This is what it says to me when I'm logging the error on creating the thread:
Exception in thread "Nathan-Transportation1" java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
Is there any way to fix it? I want to understand why it happend when I create my thread pool.
Try using #Async annotation.
For more information see here
This error message indicates that you are attempting to access request-scoped data (for example, request attributes) outside of the context of an HTTP request.
You can try the following solutions to this problem:
To expose the current request and make it accessible to your code,
use a RequestContextListener or RequestContextFilter.
To execute tasks in a background thread, use Spring's TaskExecutor interface, which will handle the necessary context management for you.
Here are some links that may be of interest to you:
RequestContextListener
RequestContextFilter
TaskExecutor
I have a use case where I have 6 steps being performed in one request. The business is requesting that we capture metrics on what the result of each step was in the process. They want us to log to a Kinesis stream.
Architecturally I am looking at the best solution. We have java based services I want to have a request scoped object enriched as the request progresses, then when the endpoint finishes we would make a service call to kinesis asynchronous using a fire and forget pattern. This way the reporting is not holding up the main thread.
I was looking at using the raw ThreadLocal or guice scope. Has anyone ran into to a similar problem that they solved? Im thinking of use guice request scoped components, which will greatly simply the code. Just looking for some opinions. Thanks!
I'm assuming you aren't on a servlet environment because, then, you will just use the built in request scope. Even then you can use the request scope from guice-servlet building the scope yourself.
void processRequest() {
RequestScoper scope = ServletScopes.scopeRequest(Collections.emptyMap());
try ( RequestScoper.CloseableScope ignored = scope.open() ) {
step1();
step2();
step3();
step4();
step5();
step6();
}
}
You can use #RequestScoped and it will be the same object on all your steps. You can, for example, use a provider to get access to it.
In my Dropwizard project, I'm defining a generic ExceptionMapper<WebApplicationException>:
environment.jersey().register(new WebApplicationExceptionMapper());
...but this doesn't seem to catch any of the 404 errors for unmatched paths.
Without defining five defaultHandler() methods for every single resource, how do I catch all 404s so I can return my own error page or some JSON?
So, if I had a service with one resrouce, say, /docs, this is the situtation:
/myservice/docs/helloworld doesn't match any #Path defined in my DocsResource. It returns a generic Jetty 404 page (not what I want)
/myservice/doesntexist returns my own error resource with the exception mapper (this is what I want everywhere)
what you need to do is to set a different Error handler. The 404's you are seeing when hitting a non-existing path, are not handled by jersey. Jersey maps exceptions for resources, but you in fact never hit the resource in the first place. This is where you will need to define an error handler:
In DefaultServerFactory, you need to overwrite:
protected Server buildServer(LifecycleEnvironment lifecycle,
ThreadPool threadPool) {
final Server server = new Server(threadPool);
server.addLifeCycleListener(buildSetUIDListener());
lifecycle.attach(server);
final ErrorHandler errorHandler = new ErrorHandler();
errorHandler.setServer(server);
errorHandler.setShowStacks(false);
server.addBean(errorHandler);
server.setStopAtShutdown(true);
server.setStopTimeout(shutdownGracePeriod.toMilliseconds());
return server;
}
(This class is in AbstractServerFactory).
You then can implement your own ErrorHandler and make it do whatever it is you want it to do.
For testing, open org.eclipse.jetty.server.handler.ErrorHandler and set a breakpoint, then try and hit a non-existing URL. It will stop there and you can see how jetty handles this sort of thing.
I hope that helps.
If you need help overwriting default DW functionality, you can look at a similar post where I described how to overwrite loggers:
Dropwizard doesn't log custom loggers to file
Cheers,
Artur
While trying to move an axis2 web-app from glassfish3 to tomcat6, I can't seem to find a way to get a config parameter from a static context.
In glassfish3, a system property was defined in a far away place and read from the application using System.getProperty(String name). Not only does the web agree that this is not the way to go for a web application, this trick is just not feasible for tomcat (tomcat docs).
Reading parameters from the ServletContext is also not feasible as the app uses axis2 and I can't seem to find a way to access any kind of servlet voodoo from the static context that initializes the app's configuration.
services.xml (the file containing the service description for axis2) can contain <parameter> nodes, so that seems a nice place to configure the configuration location, but I can't seem to find a way to read these parameters from the application.
So in short: any ideas on how to get a value configured outside the application's code available from a static context?
(answer listed here as StackOverflow does not allow me to answer my own question...)
After scouring the Internet some more, a solution was found using an implementation of org.apache.axis2.engine.ServiceLifeCycle, which could read a parameter in the startUp-method as such:
Parameter param = service.getParameter("name");
if (param != null) {
saveParamValue(param.getValue().toString());
} else {
// log warning on falling back to System.getProperty()
}
The life cycle class is attached using class="fully.qualified.ClassName" on the <service> node of the services.xml file used by axis2.
This works, now the application just crashes on something else (but that has little to with this issue).
The parameters in services.xml can be accessed by getting the ServiceContext object for the service, then calling ServiceContext.getParameter(). If your service implementation class implements the Lifecycle interface, then Axis2 will call Lifecycle.init() every time it creates a new instance of the service class. The argument to Lifecycle.init() is the service's ServiceContext. Your init() implementation could save the context object or look up the parameters that you're interested in.
I have the servlet name ExampleServlet.java which have only init method with HttpServletRequest and HttpServletResponse parameters. I will forward the request to another servlet named ForwardedServlet.java which will display some text on the web page. But when i am trying to execute the ExampleServlet http://localhost:8080/Sample/ExampleServlet
the following error occurs.
The request sent by the client was syntactically incorrect (HTTP method GET is not supported by this URL).
Please give the solution and why it this error occured...
Thanks in advance
You haven't implemented the 'doGet' method, so it's falling back to the default implementation, which is a 503 server error (or some variant).
The init is only called once, when the servlet is instantiated - it's not called once per request, which you'll need to do.
Also, make sure the capitalisation and arguments are correct; if you use something else, it won't be the right method that the Servlet API calls.