EJB persistence not working - ejb

I have a example EJB persistence with EJB module run on Jboss 5GA , JDK 6 . Default package have 3 file :
Book.java :
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="books")
public class Book implements Serializable{
private int id;
private String name;
public Book(){
}
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
#Column(name="id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
LibraryPersistentBean.java
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
#Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
#PersistenceContext(unitName="EJBModule1PU")
private EntityManager entityManager;
#Override
public void addBook(Book book) {
entityManager.persist(book);
}
#Override
public List<Book> getBooks() {
return entityManager.createQuery("From books").getResultList();
}
}
LibraryPersistentBeanRemote.java:
import java.util.List;
import javax.ejb.Remote;
#Remote
public interface LibraryPersistentBeanRemote {
void addBook(Book bookName);
List<Book> getBooks();
}
And configure files are persistence.xml and jboss-ds.xml that have lines of code :
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="EJBModule1PU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/MysqlDS</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
<local-tx-datasource>
<jndi-name>MysqlDS</jndi-name>
<connection-url>jdbc:mysql://localhost:3306/ejb_books?zeroDateTimeBehavior=convertToNull</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>root</user-name>
<password/>
<min-pool-size>5</min-pool-size>
<max-pool-size>20</max-pool-size>
<idle-timeout-minutes>5</idle-timeout-minutes>
</local-tx-datasource>
</datasources>
Client's application consist of :
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class JavaApplication1 {
public static void main(String[] args) throws NamingException {
try {
Book b = new Book();
b.setName("AI");
Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
env.put(Context.URL_PKG_PREFIXES,"org.jboss.naming:org.jnp.interfaces");
env.put(Context.PROVIDER_URL, "jnp://localhost:1099");
Context ctx = new InitialContext(env);
LibraryPersistentBeanRemote libraryBean = (LibraryPersistentBeanRemote)ctx.lookup("LibraryPersistentBean/remote");
libraryBean.addBook(b);
} catch (NamingException ex) {
Logger.getLogger(JavaApplication1.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
and jboss-client.jar, EJB Module was imported
when run, errors were occured :
Mar 7, 2017 10:30:23 AM JavaApplication1 main
SEVERE: null
javax.naming.NoInitialContextException: Cannot instantiate class: org.jnp.interfaces.NamingContextFactory [Root exception is java.lang.ClassNotFoundException: org.jnp.interfaces.NamingContextFactory]
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:657)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
at javax.naming.InitialContext.init(InitialContext.java:223)
at javax.naming.InitialContext.<init>(InitialContext.java:197)
at JavaApplication1.main(JavaApplication1.java:25)
Caused by: java.lang.ClassNotFoundException: org.jnp.interfaces.NamingContextFactory
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:46)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:654)
... 4 more
How to resolve these error ? thanks you so much !

"$JBOSS_HOME/jboss-as/client/jnp-client.jar" contains the missing class "org.jnp.interfaces.NamingContextFactory" , The "jnp-client.jar" is referred internally using the MANIFEST.MF file "class-path" entry of the "$JBOSS_HOME/client/jbossall-client.jar" file.
So the JBoss Client code users/developers need to make sure that in order to avoid the "[Caused by: java.lang.ClassNotFoundException: org.jnp.interfaces.NamingContextFactory]" exception users must include the "$JBOSS_HOME/client/jbossall-client.jar" in client's classpath.

Related

How to resolve view in thymleaf + Springboot?

Currently, i have function, which is to convert the data from MYSQL to CSV. The CSV function contain the webconfig where use the viewResolver. The problem is, when i used below function, the page cannot view but the CSV file can be download and vice versa. Is there anything that i need to configure ?
-Configure ContentNegotiatingViewResolver
#Bean
public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager(manager);
// Define all possible view resolvers
List<ViewResolver> resolvers = new ArrayList<>();
resolvers.add(csvViewResolver());
resolver.setViewResolvers(resolvers);
return resolver;
}
WebConfig- full code
package com.portal.dmtt.csvDownload.config;
import com.portal.dmtt.csvDownload.viewResolver.CsvViewResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
import java.util.ArrayList;
import java.util.List;
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer
.defaultContentType(MediaType.APPLICATION_JSON)
.favorPathExtension(true);
}
/*
* Configure ContentNegotiatingViewResolver
*/
#Bean
public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager(manager);
// Define all possible view resolvers
List<ViewResolver> resolvers = new ArrayList<>();
resolvers.add(csvViewResolver());
resolver.setViewResolvers(resolvers);
return resolver;
}
/*
* Configure View resolver to provide Csv output using Super Csv library to
* generate Csv output for an object content
*/
#Bean
public ViewResolver csvViewResolver() {
return new CsvViewResolver();
}
}
Export Controller
package com.portal.dmtt.csvDownload.controller;
import com.portal.dmtt.repo.dmttDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class ExportController {
#Autowired
private dmttDAO dmttDAO;
/**
* Handle request to download an Excel document
*/
#GetMapping("/dl")
public String download(Model model) {
model.addAttribute("results", dmttDAO.getAllResultSet());
return "";
}
}
Abstract View
package com.portal.dmtt.csvDownload.view;
import org.springframework.web.servlet.view.AbstractView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
public abstract class AbstractCsvView extends AbstractView {
private static final String CONTENT_TYPE = "text/csv";
public AbstractCsvView() {
setContentType(CONTENT_TYPE);
}
#Override
protected boolean generatesDownloadContent() {
return true;
}
#Override
protected final void renderMergedOutputModel(
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
response.setContentType(getContentType());
buildCsvDocument(model, request, response);
}
protected abstract void buildCsvDocument(
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response)
throws Exception;
}
CSV View
package com.portal.dmtt.csvDownload.view;
import com.portal.dmtt.model.exceptionMonitoring.FN_Result_Set;
import org.supercsv.io.CsvBeanWriter;
import org.supercsv.io.ICsvBeanWriter;
import org.supercsv.prefs.CsvPreference;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
public class CsvView extends AbstractCsvView {
#Override
protected void buildCsvDocument(Map<String, Object> model, HttpServletRequest request, HttpServletResponse
response) throws Exception {
response.setHeader("Content-Disposition", "attachment; filename=\"my-csv-file.csv\"");
List<FN_Result_Set> fnResultSetList = (List<FN_Result_Set>) model.get("results");
String[] header = {"SP_ID", "SP_ID", "XFER_XMIT_STATUS", "XFER_FILE_NAME", "UPDATE_TS", "YYMM", "REMARKS"};
try {
ICsvBeanWriter csvWriter = new CsvBeanWriter(response.getWriter(),
CsvPreference.STANDARD_PREFERENCE);
csvWriter.writeHeader(header);
for (FN_Result_Set user : fnResultSetList) {
csvWriter.write(user, header);
}
csvWriter.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
View Resolver
package com.portal.dmtt.csvDownload.viewResolver;
import com.portal.dmtt.csvDownload.view.CsvView;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import java.util.Locale;
public class CsvViewResolver implements ViewResolver {
#Override
public View resolveViewName(String s, Locale locale) throws Exception {
return new CsvView();
}
}
One of the problems is that your CSVViewResolver is resolving a view for any view name. You may want to return null from CSVViewResolver.resolveViewName() if s, the view name, is not empty .
Another issue is that the browser (at least my Chrome) doesn't send text/csv as Accept header, but text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Set the media type explicitly in configureContentNegotiation for CSV:
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer
.defaultContentType(MediaType.APPLICATION_JSON)
.favorPathExtension(true)
.mediaType("csv", MediaType.parseMediaType("text/csv"));
}
Remove the Bean contentNegotiatingViewResolver
You shouldn't create a contentNegotiatingViewResolver as one is provided by Spring Boot. If you provide one, you will have two of this type, and yours will not have the Thymeleaf ViewResolver. As your CSVViewResolver will return a view for any view name, the view will be resolved in the ContentNegotiatingViewResolver provided by you, not in the one provided by Spring.
Details:
The csvViewResolver bean will be picked up by the Spring Boot's ContentNegotiatingViewResolver along others like BeanNameViewResolver, ThymeleafViewResolver, ViewResolverComposite, InternalResourceViewResolver.
To debug this set a breakpoint on DispatcherServlet.resolveViewName:
protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,
HttpServletRequest request) throws Exception {
for (ViewResolver viewResolver : this.viewResolvers) {
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
return view;
}
}
return null;
}

Spring MVC Java Config issues

I am trying to do an example to change the xml config to Java config for Spring MVC. But my simple example is not working. On running this project on server, I can't see any beans initializing or the dispatcher servlet name on console.
and I get 404 error on running the http://localhost:8080/Servlet3Example/
I have created a maven project and following is my code:
package com.project.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class MyDispatcherServlet extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
System.out.println("get root config");
//return new Class[]{RootConfig.class};
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
System.out.println("get web config");
return new Class[]{WebConfig.class};
}
#Override
protected String[] getServletMappings() {
System.out.println("in dispatcher servlet");
return new String[] {"/"};
}
}
And the WebConfig is:
package com.project.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages={"com.project.controllers"})
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setSuffix(".jsp");
viewResolver.setPrefix("/WEB-INF/views/");
return viewResolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
And controller:
package com.project.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class HomeController {
#RequestMapping(value="/",method=RequestMethod.GET)
public String home()
{
return "home";
}
}
Can you please change #ComponentScan to #ComponentScan(basePackages={"com.project.*"})

Configuring Multiple View Resolvers (Thymeleaf and Json) Spring

I am trying to configure a Spring based app, where I want to configure two view resolvers. From my controller, if I return just the string name like "login", then it should be handled by the Thymeleaf resolver, whereas if the controller's method returns an object, then appropriate json view should be used. When I try to run my application as configured below, I get the following error
"Could not resolve view with name 'login' in servlet with name
'dispatcher'"
Requesting you guys to look at the Java classes below. The first is the configuration class, the second is the Controller I am trying to use.
package com.gojha.web;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
import org.thymeleaf.templateresolver.TemplateResolver;
#Configuration
#EnableWebMvc
#ComponentScan("com.gojha.web")
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean
public ViewResolver viewResolver(ContentNegotiationManager cnm) {
ContentNegotiatingViewResolver cnvr = new ContentNegotiatingViewResolver();
cnvr.setContentNegotiationManager(cnm);
return cnvr;
}
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_JSON);
}
#Bean
public TemplateResolver templateResolver() {
TemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
return templateResolver;
}
#Bean
public TemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
return templateEngine;
}
#Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine((SpringTemplateEngine) templateEngine());
return viewResolver;
}
}
Controller
package com.gojha.web;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.client.RestTemplate;
import static org.springframework.web.bind.annotation.RequestMethod.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
#Controller
#RequestMapping("/")
public class LoginController {
private RestTemplate restTemplate;
private class Test {
private String a;
public Test() {
super();
}
public Test(String a) {
super();
this.a = a;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
}
#Autowired
public LoginController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
#RequestMapping(method=GET)
public String testing(){
return "login";
}
#RequestMapping(method=GET, produces="application/json")
public Test testing2(){
return new Test("wow");
}
}
I hope the code is self-explanatory.
I got it working by changing the configuration file and allocating orders to view resolvers. From what I understand, it looks like first it tries to resolve the view using ContentNegotiation, and if it fails, falls back to Thymeleaf resolver. I am marking this as the answer, if someone has a better approach, or a suggested correction, let me know.
package com.gojha.web;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
import org.thymeleaf.templateresolver.TemplateResolver;
#Configuration
#EnableWebMvc
#ComponentScan("com.gojha.web")
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_JSON);
}
#Bean
public ViewResolver viewResolver() {
TemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine);
viewResolver.setOrder(2);
return viewResolver;
}
#Bean
public ViewResolver cnViewResolver(ContentNegotiationManager cnm) {
ContentNegotiatingViewResolver cnvr = new ContentNegotiatingViewResolver();
cnvr.setContentNegotiationManager(cnm);
cnvr.setOrder(1);
List<View> views = new ArrayList<View>();
views.add(jsonView());
cnvr.setDefaultViews(views);
return cnvr;
}
#Bean
public View jsonView() {
MappingJackson2JsonView view = new MappingJackson2JsonView();
view.setPrettyPrint(true);
return view;
}
}

WebApplicationContextUtils.getWebApplicationContext(ServletContext) returns NULL from ServletContextListener

I am unable to get WebApplicationContext inside ServletContextListener. I searched for solution but non of them are working for me. I would appreciate if any one can help. Thanks in advance.
Below are code snippets-
My AppConfig class:
package in.andonsystem.config;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"in.andonsystem"})
public class AppConfig extends WebMvcConfigurerAdapter{
#Bean
public ViewResolver viewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Bean
public MessageSource messageSource(){
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
}
}
My AppInitializer Class.
package in.andonsystem.config;
import javax.servlet.ServletRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class Appinitializer implements WebApplicationInitializer{
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(AppConfig.class);
rootContext.setServletContext(servletContext);
// Manage the lifecycle of the root application context
servletContext.addListener(new ContextLoaderListener(rootContext));
rootContext.refresh();
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher =
servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
My ContextListener Class:
package in.andonsystem.config;
import com.mysql.jdbc.AbandonedConnectionCleanupThread;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.logging.Logger;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
#WebListener
public class ContextListener implements ServletContextListener{
private Logger logger = Logger.getLogger("ContextListener");
#Override
public void contextInitialized(ServletContextEvent sce) {
logger.info("contextInitialized()");
WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
System.out.println("Is rootContext null:" + (rootContext == null));
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
stdout output is always coming true.
What am I missing?
Finally came up with the solution. The problem was that ServletContextListener was being loaded before ContextLoaderListener and Therefore a WebApplicationContext returned was null because ContextLoaderListener must be loaded before ServletContextListener in order to get the rootContext.
I removed #WebListener annotation from my ContextListener and added this Listener Programatically in onStartup method of AppInitializer after Adding ContextLoaderListener.
Now my ContextListener without #WebListener annotation is:
public class ContextListener implements ServletContextListener{
private Logger logger = Logger.getLogger("ContextListener");
#Override
public void contextInitialized(ServletContextEvent sce) {
logger.info("contextInitialized()");
WebApplicationContext rootContext =
WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
System.out.println("Is rootContext null:" + (rootContext == null));
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
logger.info("contextDestroyed()");
}
}
and AppInitializer is :
public class Appinitializer implements WebApplicationInitializer{
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(AppConfig.class);
rootContext.setServletContext(servletContext);
// Manage the lifecycle of the root application context
servletContext.addListener(new ContextLoaderListener(rootContext));
//ContextListener must be added after ContextLoaderListener
servletContext.addListener(ContextListener.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher =
servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
Looks basically correct, but I think you should remove the following 2 lines from your initializer class:
rootContext.setServletContext(servletContext);
and
rootContext.refresh();

Test case for testing a jersey web resource using grizzle is giving me 404

I tried below way which is working fine
package test;
import static org.junit.Assert.assertEquals;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.DeploymentContext;
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.ServletDeploymentContext;
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
import org.glassfish.jersey.test.spi.TestContainerException;
import org.glassfish.jersey.test.spi.TestContainerFactory;
import org.junit.Test;
import com.mkyong.rest.HelloWorldService;
public class HelloWorldServiceTest extends JerseyTest{
#Path("hello")
public static class HelloResource {
#GET
public String getHello() {
return "Hello World!";
}
}
#Override
protected Application configure() {
return new ResourceConfig(HelloResource.class);
}
#Override
protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
return new GrizzlyWebTestContainerFactory();
}
#Override
protected DeploymentContext configureDeployment() {
return ServletDeploymentContext.forPackages(
getClass().getPackage().getName()).build();
}
#Test
public void testSingleNode() throws Exception {
final String hello = target("hello").request().get(String.class);
assertEquals("Hello World!", hello);
}
}
When i tried to replace the resource with resource which is outside of this test class and package like below
package test;
import static org.junit.Assert.assertEquals;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.DeploymentContext;
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.ServletDeploymentContext;
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
import org.glassfish.jersey.test.spi.TestContainerException;
import org.glassfish.jersey.test.spi.TestContainerFactory;
import org.junit.Test;
import com.mkyong.rest.HelloWorldService;
public class HelloWorldServiceTest extends JerseyTest{
#Path("hello")
public static class HelloResource {
#GET
public String getHello() {
return "Hello World!";
}
}
#Override
protected Application configure() {
return new ResourceConfig(HelloWorldService.class);
}
#Override
protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
return new GrizzlyWebTestContainerFactory();
}
#Override
protected DeploymentContext configureDeployment() {
return ServletDeploymentContext.forPackages(
getClass().getPackage().getName()).build();
}
#Test
public void testSingleNode() throws Exception {
final String hello = target("hello").path("Test").request().get(String.class);
assertEquals("Jersey say : Test", hello);
}
}
HelloWorldService.java
package com.mkyong.rest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
#Path("/hello")
public class HelloWorldService {
#GET
#Path("/{param}")
#Produces(MediaType.APPLICATION_JSON)
public Response getMsg(#PathParam("param") String msg) {
String output = "Jersey say : " + msg;
return Response.status(200).entity(output).build();
}
}
RestApplication.java
package rest;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
import com.mkyong.rest.HelloWorldService;
public class RestApplication extends Application{
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(HelloWorldService.class);
return s;
}
}
web.xml
<web-app id="WebApp_ID" version="2.4"
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">
<display-name>Restful Web Application</display-name>
<servlet>
<servlet-name>rs-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>rest.RestApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>rs-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
I got an exception
javax.ws.rs.NotFoundException: HTTP 404 Not Found
at org.glassfish.jersey.client.JerseyInvocation.convertToException(JerseyInvocation.java:917)
at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:770)
at org.glassfish.jersey.client.JerseyInvocation.access$500(JerseyInvocation.java:90)
at org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:671)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:423)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:667)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:396)
at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:296)
at test.HelloWorldServiceTest.testSingleNode(HelloWorldServiceTest.java:48)
Can any one correct me where i went wrong...
Look at this
#Override
protected DeploymentContext configureDeployment() {
return ServletDeploymentContext.forPackages(
getClass().getPackage().getName()).build();
}
The forPackages is saying what package to scan for #Path and #Provider annotated classes, and automatically register them. The reason it works in the first example is that the resource class (the class annotated with #Path is in the getClass().getPackage().getName() package.
This method
#Override
protected Application configure() {
return new ResourceConfig(HelloWorldService.class);
}
is never called, because you override the getDeploymentContext(). Normally, if you don't override that method, it will call the configure method to register the application with the deployment context. But you neve do this.
So instead of the forPackages, you should use one of the ServletDeploymentContext.builder methods, that accept an Application class
return ServletDeploymentContext.builder(configure()).build()
return ServletDeploymentContext.builder(RestApplication.class).build();
OR
#Override
public ResourceConfig configure() {
return new ResourceConfig(HelloWorldService.class);
}
#Override
public ServletDeploymentContext configureDeployment() {
return SerlvetDeploymentContext.forServlet(new ServletContainer(configure));
}
One thing to note it that you only need to override the getTestContainerFactory and the configureDeployment if you wan to set up a servlet environment. Meaning, you need to use servlet APIs like HttpServletRequest, ServletContext, etc, in your application. If you don't need a servlet environment, just overriding configure is enough.

Resources