I am working on sample application called bookstore where I have used Dependency Injection. Very simple application. I am using JavaEE 6, GlassFish 3.1.2, Static data in a class (no db), Eclipse Juno.
I can provide more info if needed.
Error I get:
WARNING: StandardWrapperValve[com.bookstore.web.BookListServlet]: PWC1406: Servlet.service() for servlet com.bookstore.web.BookListServlet threw exception
java.lang.NullPointerException
at com.bookstore.web.BookListServlet.doGet(BookListServlet.java:29)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
This I know is Dependency is not injected. Class instance is not created to use it. If I remove #Inject and created an instance of a class than the page is loading fine.
Servlet code generating error: See bold comments
package com.bookstore.web;
import java.io.IOException;
import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.bookstore.BookRepositoryImp;
#WebServlet("/book/")
public class BookListServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
#Inject
private BookRepositoryImp bookRepo;
public BookListServlet() {
super();
}
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException,
IOException {
**//bookRepo = new BookRepositoryImp(); If uncommect this code and remove #Inject than page working fine**
req.setAttribute("books", bookRepo.listBooks());
String path = "/WEB-INF/pages/book-list.jsp";
getServletContext().getRequestDispatcher(path).forward(req, res);
}
protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException,
IOException {
}
}
Project structure:
Have you tried moving your beans.xml file into the WEB-INF folder where your web.xml lives, maybe for some reason your beans.xml file is not copied properly to the resulting war file.
Related
I'm looking for a way to register a javax.servlet.http.HttpServlet in ktor, but can't find any.
Do I need to install a feature? Register it in Routing? Can I enable scanning of #WebServlet annotations?
Example servlet:
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#WebServlet("/foo")
public class MyServlet extends HttpServlet {
#Override
protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) {
// ...
}
}
What you want is currently not supported by design. See my Feature Request and corresponding PR to add support for it.
Could anyone please help me?
Locally, on my mahcine I am running Tomcat 8.
I have used Eclipse to create a very very very simple Java Servlet by reading some online tutorials, Here's the code:
package com.theopentutorials.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class HelloWorldServlet
*/
#WebServlet("/HelloWorldServlet")
public class HelloWorldServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public HelloWorldServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("Hello World");
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
I am successfully running this servlet on my machine and can access it fine from other machines in the same domain.
My web browser simply displays the string "Hello World" as expected.
So, now I'd like to push it to CloudFoundry.
So I use eclipse to export as a WAR file. Fine.
Next to CloudFoundry and I execute the following:
cf push Karry -p FirstServlet.war
All works fine. I see CloudFoundry installing java buildpacks etc. Finally it says App Started OK.
So now I browse to the url provided and I get:
What have I done wrong?
Thanks,
Mitch.
Did you try the /HelloWorldServlet endpoint? This is where I would look for this servlet, as defined in the code in
#WebServlet("/HelloWorldServlet")
I am using Eclipse IDE, a simple HelloServlet.java file and a simple index.jsp file. When I run the local server, the program starts but the following code does not execute:
/**
* #see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
System.out.println("Init Firing: ");
}
I have the Console tab open, and the last statement I receive is: INFO: Server startup in 1442 ms. What might I do to get the init method to fire?
The container will only call the init() method of the servlet when it's called, not on the container startup.
If you want to start things on container startup, you can use the ContextListener as suggested here call method on server startup
This code works for me
package mine;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MySL extends HttpServlet {
private static final long serialVersionUID = 1L;
public void init(ServletConfig config) throws ServletException {
System.out.println("xyz="+config.getInitParameter("xyz"));
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doGet");
}
}
and web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>jsp</display-name>
<servlet>
<servlet-name>mySL</servlet-name>
<servlet-class>mine.MySL</servlet-class>
<init-param>
<param-name>xyz</param-name>
<param-value>123</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>mySL</servlet-name>
<url-pattern>/MySL</url-pattern>
</servlet-mapping>
</web-app>
When the server starts, nothing happens, because the init() method is called when the servlet is called.
On the first servlet call (e.g. opening in your browser something like http://myserver.mydomain:8080/myapp/MySL), you'll get
xyz=123
doGet
On the second servlet call, you'll get
doGet
Please notice that this is the "old way" of declaring things. Nowadays, Servlets configuration can be made using annotations. Careful to not mix annotations with XML declarations for the same servlet.
Servlets with annotations look like this
package mine;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#WebServlet(urlPatterns = { "/OtherSL" }, initParams = { #WebInitParam(name = "abc", value = "456", description = "some parameter") })
public class OtherSL extends HttpServlet {
private static final long serialVersionUID = 1L;
public void init(ServletConfig config) throws ServletException {
System.out.println("abc=" + config.getInitParameter("abc"));
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
System.out.println("doGet");
}
}
I have created a fresh new Java EE 6 Enterprise-Application in Netbeans 7.2. So I have three Projects:
EAR
EJB
WAR
In the EJB-Project, I have created a simple Bean:
package de.aidaorga.test;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
#Stateless
#LocalBean
public class NewSessionBean2343 {
}
In the WAR-Project, I have created a blank beans.xml in the folder "Web Pages\WEB-INF":
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>
And I have also created a simple Servlet:
import de.aidaorga.test.NewSessionBean2343;
import java.io.IOException;
import javax.ejb.EJB;
import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#WebServlet(name = "NewServlet2343", urlPatterns = {"/NewServlet2343"})
public class NewServlet2343 extends HttpServlet {
#Inject
NewSessionBean2343 newSessionBean2343_1;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
#Override
public String getServletInfo() {
return "Short description";
}
}
Now, Netbeans shows me a Warning "Unsatisfied dependency: no bean matches the injection point" for the field "newSessionBean2343_1" annotated with "#Inject".
At deploy time, I get the following Excpetion:
Schwerwiegend: Exception while loading the app
Schwerwiegend: Exception while loading the app : WELD-001408 Unsatisfied dependencies for type [NewSessionBean2343] with qualifiers [#Default] at injection point [[field] #Inject NewServlet2343.newSessionBean2343_1]
org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [NewSessionBean2343] with qualifiers [#Default] at injection point [[field] #Inject NewServlet2343.newSessionBean2343_1]
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:311)
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:280)
at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:143)
at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:163)
at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:382)
at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:367)
at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:380)
at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:199)
at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:128)
at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:313)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:461)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:389)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:348)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:363)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1085)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:95)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1291)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1259)
at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:461)
at com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:212)
at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:179)
at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117)
at com.sun.enterprise.v3.services.impl.ContainerMapper$Hk2DispatcherCallable.call(ContainerMapper.java:354)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:722)
Why do I get this warning and how do I get rid of it?
Thanks for any help.
Markus
I solved the problem: I've just forgotten the beans.xml in the EJB-Project. One beans.xml in an EAR-Project ist not enough...
First of all this is just an IDE warning - what counts is whether your code compiles.
The code does not look wrong, even though I can't remember that I've ever injected one bean twice. But IMHO that should work.
I reckon that Netbeans is only able to validate #Inject, but not #EJB, this would explain the warning.
Try to deploy it to a server and see what comes out.
I'm trying to register a servlet using servletContainerInitializer but it doesn't seem to work, Maybe it's my code (kindly review it), but I came to wonder about the difference between ServletContainerInitializer and ServletContextListener, because the follwing code runs fine when used as ServletContextListener instead.
From servlet 3.0 specification:
4.4
Configuration methods (adding servlets dynamically):
... or from the onStartup method of a ServletContainerInitializer implementation ...
The ServletContainerInitializer:
package com.marmoush.javaexamples.nullhaus.servlet;
import java.util.Set;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
public class MyInit implements ServletContainerInitializer {
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
System.out.println("hello");
ServletRegistration reg = ctx.addServlet("q31","com.marmoush.javaexamples.nullhaus.servlet.Q31");
reg.addMapping("/q31/*");
}
}
The servlet which I'm trying to auto-register:
package com.marmoush.javaexamples.nullhaus.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Q31 extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().println("hello world");
}
}
Original code from nullhaus java examples website "only class name edited" also didn't work!
package com.marmoush.javaexamples.nullhaus.servlet;
import java.util.Set;
import javax.servlet.Servlet;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
public class MyInit implements ServletContainerInitializer {
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
try {
Class klass = Class.forName("com.marmoush.javaexamples.nullhaus.servlet.Q31");
Class<Q31> clazz = (Class<Q31>) klass;
Servlet s = ctx.createServlet(clazz);
ServletRegistration.Dynamic d = ctx.addServlet("q31", s);
d.addMapping("/baz/*");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
The ServletContainerInitializer implementation is intented to be bundled in a JAR file which is in turn been dropped in /WEB-INF/lib of the webapp. The JAR file itself should have a /META-INF/services/javax.servlet.ServletContainerInitializer file containing the FQN of the ServletContainerInitializer implementation in the JAR. Please note that this file should thus not be placed in the webapp itself!
This allows webapp module developers to let their JAR file hook on webapp's startup and shutdown cycle. It's true that they could also have used a ServletContextListener with #WebListener for this, but this won't work if the webapp's own web.xml file has a metadata-complete="true" attribute set in <web-app> which means that the webapp shouldn't scan JARs for annotations (which saves startup time).
That the ServletContainerInitializer doesn't work in your particular case can only mean that you're actually not developing a module JAR file, but just a part integral to your own web application. In that case, the ServletContainerInitializer is useless for you and you should be using ServletContextListener instead.
#WebListener
public class Config implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent event) {
// Do stuff during server startup.
}
#Override
public void contextDestroyed(ServletContextEvent event) {
// Do stuff during server shutdown.
}
}
See also:
Map servlet programmatically instead of using web.xml or annotations
Splitting up shared code and web.xml from WAR project to common JAR project
Using special auto start servlet to initialize on startup and share application data
what is the equivalence of contextDestroyed() in ServletContainerInitializer?
Check if you have configured the ServletContainerInitializer propertly. The ServletContainerInitializer class name should be configured inside a file:
META-INF/services/javax.servlet.ServletContainerInitializer
The file should contain just the class name. For Ex in your case it should look like:
com.marmoush.javaexamples.nullhaus.servlet.MyInit
The file (META-INF/services/javax.servlet.ServletContainerInitializer) can be bundled in a library JAR in WEB-INF/lib.
Here is any example which explains.