Here are my configuration classes::
In the templateResolver() method without ServletContext parameter i get compile error so add it as a parameter and give it to ServletContextTemplateResolver(servletContext);
#Configuration
#EnableWebMvc
#ComponentScan(basePackages= {"com.packtpub.springsecurity"})
public class ThymeleafConfig {
#Bean
public ServletContextTemplateResolver templateResolver(ServletContext servletContext) {
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(servletContext);
resolver.setPrefix("/WEB-INF/templates/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
resolver.setCacheable(false);
resolver.setOrder(1);
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine(final ServletContextTemplateResolver templateResolver) {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver);
return engine;
}
#Bean
public ThymeleafViewResolver thymeleafViewResolver(final SpringTemplateEngine templateEngine) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine);
return resolver;
}
}
When i run my application i get following error:::
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method templateResolver in com.packtpub.springsecurity.web.configuration.ThymeleafConfig required a bean of type 'javax.servlet.ServletContext' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'javax.servlet.ServletContext' in your configuration.
What am i doing wrong?
thanks
Other config files are
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>chapter2</groupId>
<artifactId>chapter2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>chapter2</name>
<description>chapter 2 test</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- Spring dependencies START-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<!-- Servlet and JSP related dependencies -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!-- For datasource configuration -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
</dependency>
<!-- We will be using MySQL as our database server -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
<!-- Spring dependencies END -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20170516</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
#Configuration
//#Import({SecurityConfig.class, DataSourceConfig.class})
#ComponentScan(basePackages =
{
"com.packtpub.springsecurity.dataaccess",
"com.packtpub.springsecurity.domain",
"com.packtpub.springsecurity.service"
}
)
#PropertySource(value = {"classpath:application.properties"})
public class JavaConfig {
/**
* Note: If you want to use #PropertySource, you must create a static
* PropertySourcesPlaceholderConfigurer with the #Bean as seen here.
* #return PropertySourcesPlaceholderConfigurer
* #throws java.io.IOException
*/
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() throws IOException {
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
propertySourcesPlaceholderConfigurer.setIgnoreUnresolvablePlaceholders(Boolean.TRUE);
propertySourcesPlaceholderConfigurer.setProperties(yamlPropertiesFactoryBean().getObject());
return propertySourcesPlaceholderConfigurer;
}
#Bean
public static YamlPropertiesFactoryBean yamlPropertiesFactoryBean() {
YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
yaml.setResources(new ClassPathResource("application.yml"));
return yaml;
}
} // The end...
#Order(1)
public class SecurityWebAppInitializer
extends AbstractSecurityWebApplicationInitializer {
/**
* Don't initialize the filter directly, the Spring WebApplicationInitializer
* parent will take care of the initialization.
*/
public SecurityWebAppInitializer() {
super();
}
} // The end...
public class WebAppInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { JavaConfig.class, SecurityConfig.class, DataSourceConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebMvcConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/*" };
}
#Override
public void onStartup(final ServletContext servletContext)
throws ServletException {
// Register DispatcherServlet
super.onStartup(servletContext);
// Register H2 Admin console:
ServletRegistration.Dynamic h2WebServlet = servletContext.addServlet("h2WebServlet",
"org.h2.server.web.WebServlet");
h2WebServlet.addMapping("/admin/h2/*");
h2WebServlet.setInitParameter("webAllowOthers", "true");
}
} // The End...
#Configuration
#EnableWebMvc
#Import({ThymeleafConfig.class})
#ComponentScan(basePackages = {
"com.packtpub.springsecurity.web.controllers",
"com.packtpub.springsecurity.web.model"
})
public class WebMvcConfig extends WebMvcConfigurerAdapter
{
#Autowired
private ThymeleafViewResolver thymeleafViewResolver;
/**
* We mention this in the book, but this helps to ensure that the intercept-url patterns prevent access to our
* controllers. For example, once security has been applied for administrators try commenting out the modifications
* to the super class and requesting <a
* href="http://localhost:800/calendar/events/.html">http://localhost:800/calendar/events/.html</a>. You will
* observe that security is bypassed since it did not match the pattern we provided. In later chapters, we discuss
* how to secure the service tier which helps mitigate bypassing of the URL based security too.
*/
// FIXME: FInd out what this is and why it is here.
#Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping result = new RequestMappingHandlerMapping();
result.setUseSuffixPatternMatch(false);
result.setUseTrailingSlashMatch(false);
return result;
}
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/")
.setCachePeriod(31_556_926)
;
}
#Override
public void configureContentNegotiation(final ContentNegotiationConfigurer configurer) {
configurer
.ignoreAcceptHeader(false)
.favorPathExtension(true) // .html / .json / .ms
.defaultContentType(MediaType.TEXT_HTML) // text/html
.mediaTypes(
new HashMap<String, MediaType>(){
{
put("html", MediaType.TEXT_HTML);
put("xml", MediaType.APPLICATION_XML);
put("json", MediaType.APPLICATION_JSON);
}
})
;
}
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new MappingJackson2HttpMessageConverter());
}
/*#Bean
public ContentNegotiatingViewResolver contentNegotiatingViewResolver() {
ContentNegotiatingViewResolver result = new ContentNegotiatingViewResolver();
Map<String, String> mediaTypes = new HashMap<>();
mediaTypes.put("json", MediaType.APPLICATION_JSON_VALUE);
// result.setMediaTypes(mediaTypes);
result.setDefaultViews(Collections.singletonList(jacksonView()));
return result;
}*/
#Bean
public MappingJackson2JsonView jacksonView() {
MappingJackson2JsonView jacksonView = new MappingJackson2JsonView();
jacksonView.setExtractValueFromSingleKeyModel(true);
Set<String> modelKeys = new HashSet<String>();
modelKeys.add("events");
modelKeys.add("event");
jacksonView.setModelKeys(modelKeys);
return jacksonView;
}
#Override
public void configureViewResolvers(final ViewResolverRegistry registry) {
registry.viewResolver(thymeleafViewResolver);
}
// i18N support
#Bean
public ReloadableResourceBundleMessageSource messageSource() {
ReloadableResourceBundleMessageSource resource = new ReloadableResourceBundleMessageSource();
resource.setBasenames("/WEB-INF/locales/messages");
resource.setDefaultEncoding("UTF-8");
resource.setFallbackToSystemLocale(Boolean.TRUE);
return resource;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){
configurer.enable();
}
}
UPDATED
I have deleted the following dependencies from the POM according to #Adina in the comment below but still get the errors
<!-- dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency-->
What else can i do again
After some debugging on your code, the real problem is that you are autowiring ThymeleafViewResolver in the configuration responsible to configure servlet context.
public class WebMvcConfig implements WebMvcConfigurer{
#Autowired
private ThymeleafViewResolver thymeleafViewResolver;
The main problem is that before initializing your ServletContext, the application will try to initialize the ServletContextTemplateResolver (autowired will impose bean order initialization) and as you've noticed it depends on ServletContext.
Solution :
delete ThymeleafConfig class
don't autowire ThymeleafViewResolver in WebMvcConfig
and don't override method configureViewResolvers.
Don't worry, Thymeleaf will be set by default as the viewResolver.
Most of the config you've provided is already "taken care" by spring-boot-starter-thymeleaf.
If you want just to change default view directory resolver, you can just add in application.properties
spring.mvc.view.prefix=/WEB-INF/templates/
spring.mvc.view.suffix=.html
P.S: Take extra care when you override default definition from spring starters, as you can see these types of bugs are not easy to find.
Related
Initially, I started the project with IntelliJ Idea Tomcat Local Server configuration (everything worked), but decided to use Spring Boot Application. I added the main class, changed pom.xml (delete spring-context and add spring-boot-starter-parent, spring-boot, spring-boot-starter-tomcat, spring-boot-starter-web, spring-boot-autoconfigure), after that application runs , GET-Method works, but POST - not supported. Help me please!!! Thank you!
Main.class
#SpringBootApplication(scanBasePackageClasses = {SpringConfig.class})
public class Main extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
Pom.xml to springBoot
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.11.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
Main configuration class
#Configuration
#ComponentScan("ru")
#PropertySource("classpath:application.properties")
#EnableWebMvc
public class SpringConfig implements WebMvcConfigurer {
private final ApplicationContext applicationContext;
#Autowired
public SpringConfig(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
/*
* Dispatcher configuration for serving static resources
*/
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
WebMvcConfigurer.super.addResourceHandlers(registry);
registry.addResourceHandler("/images/**").addResourceLocations("/images/");
registry.addResourceHandler("/webjars/bootstrap/4.6.0/css/**").addResourceLocations("/webjars/bootstrap/4.6.0/css/bootstrap.min.css");
registry.addResourceHandler("assets/select2-develop/**").addResourceLocations("/assets/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
}
/*
* Message externalization/internationalization
*/
#Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("Messages");
return messageSource;
}
#Bean
public SpringResourceTemplateResolver templateResolver(){
// SpringResourceTemplateResolver automatically integrates with Spring's own
// resource resolution infrastructure, which is highly recommended.
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(this.applicationContext);
templateResolver.setPrefix("/WEB-INF/views/");
templateResolver.setSuffix(".html");
templateResolver.setCharacterEncoding("UTF-8");
// HTML is the default value, added here for the sake of clarity.
templateResolver.setTemplateMode(TemplateMode.HTML);
// Template cache is true by default. Set to false if you want
// templates to be automatically updated when modified.
templateResolver.setCacheable(true);
return templateResolver;
}
#Bean
public SpringTemplateEngine templateEngine(){
// SpringTemplateEngine automatically applies SpringStandardDialect and
// enables Spring's own MessageSource message resolution mechanisms.
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
// Enabling the SpringEL compiler with Spring 4.2.4 or newer can
// speed up execution in most scenarios, but might be incompatible
// with specific cases when expressions in one template are reused
// across different data types, so this flag is "false" by default
// for safer backwards compatibility.
templateEngine.setEnableSpringELCompiler(true);
return templateEngine;
}
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setCharacterEncoding("UTF-8");
registry.viewResolver(resolver);
}
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUrl("jdbc:postgresql://localhost:5432/postgres");
dataSource.setUsername("over");
// dataSource.setPassword("postgres"); Можно установить пароль для базы данных.
return dataSource;
}
#Bean
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(dataSource());
}
}
DispatcherSerlvet config
public class MySpringMvcDispatcherSerlvetIntitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
/* Класс знает теперь где находится spring конфигурация */
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringConfig.class};
}
/* Все http запросы от пользователя посылаем на dispatcher servlet */
#Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
#Override
public void onStartup(ServletContext aServletContext) throws ServletException {
super.onStartup(aServletContext);
registerCharacterEncodingFilter(aServletContext);
registerHiddenFieldFilter(aServletContext);
}
private void registerHiddenFieldFilter(ServletContext aContext) {
aContext.addFilter("hiddenHttpMethodFilter",
new HiddenHttpMethodFilter()).addMappingForUrlPatterns(null ,true, "/*");
}
private void registerCharacterEncodingFilter(ServletContext aContext) {
EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD);
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
FilterRegistration.Dynamic characterEncoding = aContext.addFilter("characterEncoding", characterEncodingFilter);
characterEncoding.addMappingForUrlPatterns(dispatcherTypes, true, "/*");
}
}
This is my exeption :
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.logException - Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
Controller
#RequestMapping("/categories")
#Controller
public class CategoriesController {
private CategoriesDao categoriesDAO;
#Autowired
public void setCategoriesDAO(CategoriesDao categoriesDAO)
{
this.categoriesDAO = categoriesDAO;
}
#GetMapping
public String index(Model model) {
model.addAttribute("category", new Category());
model.addAttribute("categories", categoriesDAO.index());
return "categories/index";
}
#PostMapping
public String addCategory(#ModelAttribute("category") #Valid Category category,
BindingResult bindingResult, Model model) {
if(bindingResult.hasErrors()) {
model.addAttribute("categories", categoriesDAO.index());
return "categories/index";
}
categoriesDAO.addCategory(category);
return "redirect:categories";
}
#DeleteMapping("/{id}")
public String deleteCategory(#PathVariable("id") int id) {
categoriesDAO.deleteCategory(id);
return "redirect:/categories";
}
#GetMapping("/{id}/edit")
public String editCategory(Model model, #PathVariable("id") int id) {
model.addAttribute("editCategory", categoriesDAO.editCategory(id));
return "categories/edit";
}
#PatchMapping("/{id}")
public String updateCategory(#ModelAttribute("editCategory") Category updateCategory,
#PathVariable("id") int id) {
categoriesDAO.updateCategory(id, updateCategory);
return "redirect:{id}/edit";
}
}
To implement the configure method in the main class you could do:
#SpringBootApplication
public class Main extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
#Override
protected SpringApplicationBuilder configure(
SpringApplicationBuilder builder) {
return builder.sources(Main.class);
}
}
I think these dependencies should be enough (assuming you are using Thymeleaf):
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.11.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
EDIT: Your ModelAttribute 'Category' might not be parsed successfully. Either the mapping fails, or maybe the validation? You might find out by adding an error handler and/or debugging the sessions.
Other ideas: Use #RestController instead of #Controller. Try to make the request mappings more explicit. Instead of on the class, put one on each method:
#RequestMapping(value = "/categories", produces = "application/json", method=RequestMethod.GET)
public String index(Model model) {
...
#RequestMapping(value = "/categories", produces = "application/json", method=RequestMethod.POST)
public String addCategory(#ModelAttribute("category") #Valid Category category,
BindingResult bindingResult, Model model) {
...
Thanks everyone! I found answer on my question. It was some problems with HiddenHttpMethodFilter. I just added this code in my Spring Config and extra dependencies was . It stared to work!!!
public FilterRegistrationBean<HiddenHttpMethodFilter> hiddenHttpMethodFilter() {
FilterRegistrationBean<HiddenHttpMethodFilter> filterRegistrationBean =
new FilterRegistrationBean<HiddenHttpMethodFilter>(new HiddenHttpMethodFilter());
filterRegistrationBean.setUrlPatterns(Collections.singletonList("/*"));
return filterRegistrationBean;
}
I have trouble to deploy my web app into a remote server.
It works completely fine when it's running on my machine - localhost:8080. (running fine at both cases at local machine where Tomcat started manually using .war file in webapps folder and, Eclipse - "run on server")
But I get 404 error when I try to connect after copying .war file into /webapps/ folder in remote server.
( I examed another sample.war file in the remote server, and it works fine. but not my .war file.)
I made .war file using command
$ mvn package
There is no web.xml file. and every configuration was made by java annotation.
I Used Tomcat9.
Also, I installed MySQL into Remote server. and managed everything in DB.
ExceptionHandlers.java
package com.rainbowtape.boards.config;
#ControllerAdvice
public class ExceptionHandlers {
#ExceptionHandler(NoHandlerFoundException.class)
public String handle(Exception ex) {
return "404";
}
}
MyServletInitializer.java
package com.rainbowtape.boards.config;
public class MyServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
servletContext.addListener(new SessionListener());
}
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { PersistenceConfig.class, WebSecurityConfig.class, };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { SpringConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
boolean done = registration.setInitParameter("throwExceptionIfNoHandlerFound", "true"); // -> true
if(!done) throw new RuntimeException();
}
#Override
protected Filter[] getServletFilters() {
return new Filter[] {
new OpenEntityManagerInViewFilter()
};
}
}
NoHandlerFoundControllerAdvice.java
package com.rainbowtape.boards.config;
#ControllerAdvice
public class NoHandlerFoundControllerAdvice {
#ExceptionHandler(NoHandlerFoundException.class)
public String handle(Exception ex) {
return "redirect:/404";
}
}
PersistenceConfig.java
package com.rainbowtape.boards.config;
#Configuration
#EnableTransactionManagement
#ComponentScan({"com.rainbowtape.boards"})
#EnableJpaRepositories(basePackages = {"com.rainbowtape.boards.dao"})
#PropertySource({"classpath:persistence-mysql.properties"})
public class PersistenceConfig {
#Autowired
private Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getRequiredProperty("jdbc.url"));
dataSource.setUsername(env.getRequiredProperty("jdbc.user"));
dataSource.setPassword(env.getRequiredProperty("jdbc.pass"));
return dataSource;
}
#Bean
public Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", env.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", env.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.hbm2ddl.auto", env.getRequiredProperty("hibernate.hbm2ddl.auto"));
return properties;
}
#Bean
#Autowired
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
entityManagerFactoryBean.setPackagesToScan("com.rainbowtape.boards.entity");
entityManagerFactoryBean.setJpaProperties(hibernateProperties());
return entityManagerFactoryBean;
}
#Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
}
SecurityWebApplicationInitializer.java
package com.rainbowtape.boards.config;
#Configuration
#EnableWebMvc
#EnableSpringDataWebSupport
#ComponentScan(basePackages = "com.rainbowtape.boards")
public class SpringConfig extends WebMvcConfigurerAdapter {
#Autowired
private Environment env;
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
registry.addResourceHandler("/images/**").addResourceLocations("file:///Users/rainbowtape/liffey-app/images/").setCachePeriod(0);
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean
public SpringResourceTemplateResolver templateResolver() {
final SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setCacheable(false);
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
return templateResolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
final SpringTemplateEngine springTemplateEngine = new SpringTemplateEngine();
springTemplateEngine.addTemplateResolver(templateResolver());
springTemplateEngine.addDialect(new SpringSecurityDialect());
return springTemplateEngine;
}
#Bean
public ThymeleafViewResolver viewResolver() {
final ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setOrder(1);
viewResolver.setContentType("text/html;charset=UTF-8");
return viewResolver;
}
#Bean
public JavaMailSender getJavaMailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost("smtp.gmail.com");
mailSender.setPort(587);
mailSender.setUsername(env.getRequiredProperty("gmail.username"));
mailSender.setPassword(env.getRequiredProperty("gmail.password"));
Properties props = mailSender.getJavaMailProperties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.debug", "true");
return mailSender;
}
#Bean
public CommonsMultipartResolver multipartResolver(){
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setDefaultEncoding("utf-8");
resolver.setResolveLazily(false);
resolver.setMaxUploadSize(10000000);
return resolver;
}
}
WebSecurityConfig.java
package com.rainbowtape.boards.config;
#PropertySource({"classpath:maildata.properties"})
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger log = LoggerFactory.getLogger(WebSecurityConfig.class);
#Autowired
private UserService userService;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public BCryptPasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
filter.setForceEncoding(true);
http.addFilterBefore(filter,CsrfFilter.class);
http
.csrf().disable() // https://stackoverflow.com/questions/28716632/spring-boot-request-method-post-not-supported
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.antMatchers("/images/**").permitAll()
.antMatchers("/registerForm").permitAll()
.antMatchers("/forgotPassword/**").permitAll()
.antMatchers("/api/school/**").permitAll()
.antMatchers("/school/**").permitAll()
.antMatchers("/","/403","/register","/login","/loginError","/dbError","/404","/error","/validateLogin","/consulting","/test").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("USER","ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/validateLogin").permitAll()
.successHandler(loginSuccessHandler())
.failureHandler(loginFailureHandler())
.and()
.logout()
.permitAll().logoutSuccessUrl("/")
.invalidateHttpSession(true)
.and()
.exceptionHandling()
.accessDeniedPage("/403");
}
private AuthenticationFailureHandler loginFailureHandler() {
return (request, response, exception) -> {
if(exception.getMessage().contains("JDBC")) {
response.sendRedirect(request.getContextPath()+"/dbError");
} else {
response.sendRedirect(request.getContextPath()+"/loginError");
}
};
}
private AuthenticationSuccessHandler loginSuccessHandler() {
return (request, response, authentication) -> {
if(authentication.getAuthorities().size() == 0) {
log.info("User has no role.");
response.sendRedirect(request.getContextPath()+"/403");
} else if(isAdmin(authentication)) {
log.info("Admin");
response.sendRedirect(request.getContextPath()+"/admin/");
} else {
log.info("UserPage Redirecting");
response.sendRedirect(request.getContextPath()+"/user/");
}
};
}
private boolean isAdmin(Authentication auth) {
System.err.println("isadmin?? - " + auth.getAuthorities().toString());
boolean isAdmin = false;
Iterator<? extends GrantedAuthority> i = auth.getAuthorities().iterator();
while (i.hasNext()) {
if(i.next().toString().contains("ADMIN")) {
isAdmin = true;
break;
}
}
return isAdmin;
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.rainbowtape</groupId>
<artifactId>boards</artifactId>
<name>spring-mvc-hibernate-boards</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<java-version>1.8</java-version>
<org.springframework-version>4.3.4.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
<dependencies>
<!-- url parsing :: https://mvnrepository.com/artifact/com.twitter.twittertext/twitter-text -->
<dependency>
<groupId>com.twitter.twittertext</groupId>
<artifactId>twitter-text</artifactId>
<version>3.0.1</version>
</dependency>
<!-- file upload :: https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<!-- mail :: https://mvnrepository.com/artifact/javax.mail/mail -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<!-- mail :: https://mvnrepository.com/artifact/org.springframework/spring-context-support -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
<!-- dealing with html :: https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.8.3</version>
</dependency>
<!-- jackson json bind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<!-- commons-beanutils -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
<!-- thymeleaf-extras-springsecurity4 -->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>3.0.2.RELEASE</version>
</dependency>
<!-- spring data jpa -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.11.15.RELEASE</version>
</dependency>
<!-- thymeleap -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>3.0.9.RELEASE</version>
</dependency>
<!-- spring-security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.mindrot</groupId>
<artifactId>jbcrypt</artifactId>
<version>0.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.12</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.3.3.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.7.Final</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
<!-- #Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>liffeyapp</finalName>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<additionalProjectnatures>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>org.test.int1.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.properties
server.contextPath=/liffeyapp
Can't fugure out, what was wrong... Would anyone help me?
Thanks in advance.
EDIT
I am adding my remote server's catalina.out - log.
23-Feb-2019 00:24:33.066 INFO [ContainerBackgroundProcessor[StandardEngine[Catalina]]] org.apache.catalina.startup.HostConfig.undeploy Undeploying context [/liffeyapp]
23-Feb-2019 00:24:43.174 INFO [ContainerBackgroundProcessor[StandardEngine[Catalina]]] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/opt/tomcat/webapps/liffeyapp.war]
23-Feb-2019 00:24:43.194 SEVERE [ContainerBackgroundProcessor[StandardEngine[Catalina]]] org.apache.catalina.startup.ContextConfig.beforeStart Exception fixing docBase for context [/liffeyapp]
java.util.zip.ZipException: zip END header not found
at java.base/java.util.zip.ZipFile$Source.zerror(ZipFile.java:1527)
at java.base/java.util.zip.ZipFile$Source.findEND(ZipFile.java:1428)
at java.base/java.util.zip.ZipFile$Source.initCEN(ZipFile.java:1435)
at java.base/java.util.zip.ZipFile$Source.<init>(ZipFile.java:1266)
at java.base/java.util.zip.ZipFile$Source.get(ZipFile.java:1229)
at java.base/java.util.zip.ZipFile$CleanableResource.<init>(ZipFile.java:825)
at java.base/java.util.zip.ZipFile$CleanableResource$FinalizableResource.<init>(ZipFile.java:852)
at java.base/java.util.zip.ZipFile$CleanableResource.get(ZipFile.java:841)
at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:245)
at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:175)
at java.base/java.util.jar.JarFile.<init>(JarFile.java:341)
at java.base/sun.net.www.protocol.jar.URLJarFile.<init>(URLJarFile.java:103)
at java.base/sun.net.www.protocol.jar.URLJarFile.getJarFile(URLJarFile.java:72)
at java.base/sun.net.www.protocol.jar.JarFileFactory.get(JarFileFactory.java:99)
at java.base/sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.java:125)
at java.base/sun.net.www.protocol.jar.JarURLConnection.getJarFile(JarURLConnection.java:92)
at org.apache.catalina.startup.ExpandWar.expand(ExpandWar.java:130)
at org.apache.catalina.startup.ContextConfig.fixDocBase(ContextConfig.java:605)
at org.apache.catalina.startup.ContextConfig.beforeStart(ContextConfig.java:738)
at org.apache.catalina.startup.Conte
.
.
.
ContextLoader ----> ERROR: 2019-02-23 00:25:19,261 ----> Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in com.rainbowtape.boards.config.PersistenceConfig: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:856)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4641)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5109)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:742)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:718)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:703)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:986)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1858)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:514)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
.
.
.
EDIT 2
Jave runtime verison was same.
Local
~:🛸 java -version
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
Remote Server
root#vps*******:~# java -version
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
I don't know what was wrong. but what I did was..
I clean the project and delete everything in .m2/.repository
and.
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.4.0-b180830.0359</version>
</dependency>
This fixed my problem.
Could it be you are compiling using Java 8 but running in Java 11?
java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
jaxb was deprecated from Java 9 and then removed in Java 11 (http://openjdk.java.net/jeps/320). Maybe the Java runtime version is the difference between your local and remote server.
I am using Spring Boot and JSP to learn some quick tutorials in Spring Security but my controller mappings and index.jsp are not working. It seems it can't locate the JSP pages. Here is my config and project structure:
springsecurity-for-reactive-apps [boot] - Project folder
- src/main/java
- com.springsecurity
- SpringsecurityForReactiveAppsApplication.java
- com.springsecurity.config
- ApplicationConfig.java
- SecurityWebApplicationInitializer.java
- SpringMvcWebApplicationInitializer.java
- SpringSecurityConfig.java
- WebApplicationConfig.java
- src
- main
- webapp
- WEB-INF
- view
- home.jsp
- index.jsp
com.springsecurity package contains
#SpringBootApplication
public class SpringsecurityForReactiveAppsApplication {
public static void main(String[] args) {
SpringApplication.run(SpringsecurityForReactiveAppsApplication.class, args);
}
}
com.springsecurity.config package contains the following classes
#Configuration
public class ApplicationConfig {
#Value("${spring.datasource.driver-class-name}")
private String DB_DRIVER;
#Value("${spring.datasource.password}")
private String DB_PASSWORD;
#Value("${spring.datasource.url}")
private String DB_URL;
#Value("${spring.datasource.username}")
private String DB_USERNAME;
#Autowired
private Environment env;
#Bean
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(DB_DRIVER);
dataSource.setUrl(DB_URL);
dataSource.setUsername(DB_USERNAME);
dataSource.setPassword(DB_PASSWORD);
return dataSource;
}
}
And SecurityWebApplicationInitializer class is
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer{
}
SpringMvcWebApplicationInitializer class is
public class SpringMvcWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { WebApplicationConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
And my configuration class is
#Configuration
#EnableWebSecurity
//#EnableAutoConfiguration(exclude = {SecurityAutoConfiguration.class })
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter{
#Autowired
private DataSource dataSource;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select username, password, enabled"
+ " from users where username = ?")
.authoritiesByUsernameQuery("select username, authority "
+ "from authorities where username = ?")
.passwordEncoder(new BCryptPasswordEncoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().hasAnyRole("ADMIN", "USER")
.and()
.httpBasic(); // Use Basic authentication
}
}
And
#Configuration
#EnableWebMvc
#ComponentScan(basePackages= {"com.springsecurity"})
public class WebApplicationConfig implements WebMvcConfigurer{
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp().prefix("/WEB-INF/view/").suffix(".jsp");
}
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
- com.springsecurity.controller contains:
#Controller
public class HomeController {
#GetMapping("/home")
public String home(Model model, Principal principal) {
System.out.println("___________home()___________________");
return "home";
}
#GetMapping("/error")
public String error(Model model, Principal principal) {
System.out.println("___________ERROR-<<error___________________");
return "home";
}
}
POM.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.springsecurity</groupId>
<artifactId>springsecurity-for-reactive-apps</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springsecurity-for-reactive-apps</name>
<description>Spring security for reactive applications</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring dependencies START-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<!-- Servlet and JSP related dependencies -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!-- For datasource configuration -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
</dependency>
<!-- We will be using MySQL as our database server -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
<!-- Spring dependencies END -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
When I go to http://localhost:8080, I get this page
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Thu Oct 18 03:24:51 CEST 2018
There was an unexpected error (type=Not Found, status=404).
No message available
The error page is mapped to show the home.jsp but I get the above page
1.viewResolver.setPrefix("/WEB-INF/views/"); views -> view
2.you can implements ErrorController in spring
#Controller
public class ViewController implements ErrorController {
#GetMapping("/home")
public String home(Model model) {
System.out.println("___________home()___________________");
return "home";
}
#GetMapping("/error")
public String error(Model model) {
System.out.println("___________ERROR-<<error___________________");
return "home";
}
#Override
public String getErrorPath() {
return "/error";
}
}
In your pom.xml remove
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>1.2.1</version>
</dependency>
And add these dependency
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
As I know, to render jsp page in boot tomcat-embed-jasper is needed.
Hello experts,
I'm currently learning Spring Boot and I want to use it with Spring Security ACL.
Following the documentation of Spring Security and a tutorial on Baeldung.com, I think I got an understanding about what is needed. I also looked into the DMS example of Spring. I stumbled across another example by searching for a solution.
Based on this information, I have build my application. For reference, you can find the current application on GitHub.
The current issue
When I start the application, I'm getting a java.lang.IllegalStateException: No ServletContext set thrown. As far as I understand, this is due to the fact that during Spring Boot's auto-configure magic, my #Configuration annotated classes are initialized before the ServletContext is initialized.
Link to full stack trace on pastebin.
What I have done so far
Based on my research (mostly on StackOverflow) and my current understanding of the issue, it should help to put the responsible Beans into an own #Configuration annotated class. Unfortunately, here I'm currently lost.
Related questions led me to this thinking (see this question, or this one.)
My environment
macOS 10.12.6
jdk1.8.0_144
IntelliJ IDEA 2017.3.3 (Ultimate Edition)
Spring Boot v1.5.9.RELEASE
Relevant project files
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.moritzrupp</groupId>
<artifactId>traderdiary</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Trader Diary</name>
<description>Trader Diary is an easy to use web application to create a journal
about your trades with great reporting on top of it.</description>
<licenses>
<license>
<name>GNU General Public License (GPL) v3.0</name>
<url>https://www.gnu.org/licenses/gpl-3.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>moritzrupp</id>
<name>Moritz Rupp</name>
<email>moritz.rupp#gmail.com</email>
<url>https://www.moritzrupp.de</url>
<timezone>DE</timezone>
</developer>
</developers>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-hal-browser</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-acl</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.11</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
application.properties
# --------------------------------------------
# Datasource Properties
# --------------------------------------------
spring.h2.console.enabled=true
spring.h2.console.path=/h2
spring.datasource.url=jdbc:h2:mem:trader-diary-h2-db
spring.datasource.platform=h2
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
TraderDiaryApplication.java
#SpringBootApplication
public class TraderDiaryApplication {
public static void main(String[] args) {
SpringApplication.run(TraderDiaryApplication.class, args);
}
}
DataSourceConfig.java
#Configuration
public class DataSourceConfig {
#Bean
public DataSource traderDiaryDataSource(DataSourceProperties
dataSourceProperties) {
return dataSourceProperties.initializeDataSourceBuilder().build();
}
}
WebSecurityConfig.java
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
#Qualifier("traderDiaryDataSource")
private DataSource dataSource;
#Override
protected void configure(HttpSecurity http) throws Exception {
// I think it is not relevant for the issue, see GitHub repo
...
}
#Bean
public PasswordEncoder passwordEncoder() {
// I think it is not relevant for the issue, see GitHub repo
...
}
#Bean
public DaoAuthenticationProvider daoAuthenticationProvider(...) {
// I think it is not relevant for the issue, see GitHub repo
...
}
#Bean
public MethodSecurityExpressionHandler aclExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler =
new DefaultMethodSecurityExpressionHandler();
AclPermissionCacheOptimizer permissionCacheOptimizer =
new AclPermissionCacheOptimizer(aclService());
expressionHandler.setPermissionEvaluator(permissionEvaluator());
expressionHandler
.setPermissionCacheOptimizer(permissionCacheOptimizer);
return expressionHandler;
}
#Bean
public PermissionEvaluator permissionEvaluator() {
return new AclPermissionEvaluator(aclService());
}
#Bean
public JdbcMutableAclService aclService() {
return new JdbcMutableAclService(dataSource, lookupStrategy(),
aclCache());
}
#Bean
public LookupStrategy lookupStrategy() {
return new BasicLookupStrategy(dataSource, aclCache(),
aclAuthorizationStrategy(), new ConsoleAuditLogger());
}
#Bean
public EhCacheBasedAclCache aclCache() {
return new EhCacheBasedAclCache(aclEhCacheFactoryBean().getObject(),
permissionGrantingStrategy(), aclAuthorizationStrategy());
}
#Bean
public EhCacheFactoryBean aclEhCacheFactoryBean() {
EhCacheFactoryBean ehCacheFactoryBean = new EhCacheFactoryBean();
ehCacheFactoryBean.setCacheManager(aclCacheManager().getObject());
ehCacheFactoryBean.setCacheName("aclCache");
return ehCacheFactoryBean;
}
#Bean
public EhCacheManagerFactoryBean aclCacheManager() {
return new EhCacheManagerFactoryBean();
}
#Bean
public PermissionGrantingStrategy permissionGrantingStrategy() {
return new DefaultPermissionGrantingStrategy(new
ConsoleAuditLogger());
}
#Bean
public AclAuthorizationStrategy aclAuthorizationStrategy() {
return new AclAuthorizationStrategyImpl(
new SimpleGrantedAuthority("ROLE_ADMIN"));
}
/* This is due to an earlier issue: DataSource required */
#Configuration
protected static class AclMethodSecurityConfig extends
GlobalMethodSecurityConfiguration {
#Autowired
#Qualifier("daoAuthenticationProvider")
private AuthenticationProvider authenticationProvider;
#Autowired
#Qualifier("aclExpressionHandler")
private MethodSecurityExpressionHandler aclExpressionHandler;
#Autowired
public void configureAuthManager(AuthenticationManagerBuilder
authenticationManagerBuilder) {
authenticationManagerBuilder
.authenticationProvider(authenticationProvider);
}
#Override
protected MethodSecurityExpressionHandler
createExpressionHandler() {
return aclExpressionHandler;
}
}
}
Thanks a lot for all input! If any further information is required, I will happily provide it.
Thanks and best regards
Moritz
Hey all,
I managed to resolve the issue myself. I did a step-by-step approach with commenting/uncommenting all the MethodSecurity related stuff.
I pin-pointed it down to the creation of the DefaultMethodSecurityExpressionHandler. This was causing the IllegalStateException: No ServletContext set.
Then, I have created a new Class MethodSecurityConfig.java and I put all the related code there. Now the application is starting again and I can continue with the developed.
#Rakesh: Thanks for your input!
MethodSecurityConfig.java
#Configuration
public class MethodSecurityConfig {
private DataSource dataSource;
#Autowired
#Qualifier("traderDiaryDataSource")
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
#Bean
public MethodSecurityExpressionHandler aclExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler =
new DefaultMethodSecurityExpressionHandler();
AclPermissionCacheOptimizer permissionCacheOptimizer =
new AclPermissionCacheOptimizer(aclService());
expressionHandler.setPermissionEvaluator(permissionEvaluator());
expressionHandler
.setPermissionCacheOptimizer(permissionCacheOptimizer);
return expressionHandler;
}
#Bean
public PermissionEvaluator permissionEvaluator() {
return new AclPermissionEvaluator(aclService());
}
#Bean
public JdbcMutableAclService aclService() {
return new JdbcMutableAclService(dataSource,
lookupStrategy(), aclCache());
}
#Bean
public LookupStrategy lookupStrategy() {
return new BasicLookupStrategy(dataSource, aclCache(),
aclAuthorizationStrategy(), new ConsoleAuditLogger());
}
#Bean
public EhCacheBasedAclCache aclCache() {
return new EhCacheBasedAclCache(aclEhCacheFactoryBean().getObject(),
permissionGrantingStrategy(), aclAuthorizationStrategy());
}
#Bean
public EhCacheFactoryBean aclEhCacheFactoryBean() {
EhCacheFactoryBean ehCacheFactoryBean = new EhCacheFactoryBean();
ehCacheFactoryBean.setCacheManager(aclCacheManager().getObject());
ehCacheFactoryBean.setCacheName("aclCache");
return ehCacheFactoryBean;
}
#Bean
public EhCacheManagerFactoryBean aclCacheManager() {
return new EhCacheManagerFactoryBean();
}
#Bean
public PermissionGrantingStrategy permissionGrantingStrategy() {
return new DefaultPermissionGrantingStrategy(
new ConsoleAuditLogger());
}
#Bean
public AclAuthorizationStrategy aclAuthorizationStrategy() {
return new AclAuthorizationStrategyImpl(
new SimpleGrantedAuthority("ROLE_ADMIN"));
}
}
WebSecurityConfig.java
#Configuration
#EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
...
#Configuration
protected static class AclMethodSecurityConfig
extends GlobalMethodSecurityConfiguration {
private MethodSecurityExpressionHandler aclExpressionHandler;
#Autowired
#Qualifier("aclExpressionHandler")
public void setAclExpressionHandler(
MethodSecurityExpressionHandler aclExpressionHandler) {
this.aclExpressionHandler = aclExpressionHandler;
}
#Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return aclExpressionHandler;
}
}
}
Just to follow up on your own answer and my previous comment where I was also lost with this one (for over 2 days!). In the end it was also overriding the configure(AuthenticationManagerBuilder auth) method in a subclass of GlobalMethodSecurityConfiguration which was also annotated with #EnableGlobalMethodSecurity.
As I am new to Spring I am unfortunately unable to provide details as to why this is the way but if I put the configuring of the AuthenticationManagerBuilder in a class that extends WebSecurityConfigurereAdapter (like I originally had) then I always end up getting a IllegalStateException: No ServletContext set error.
Here is the final code I used:
#Configuration
#EnableGlobalMethodSecurity( prePostEnabled = true, securedEnabled = true )
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
#Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return defaultMethodSecurityExpressionHandler();
}
#Override
protected void configure( final AuthenticationManagerBuilder authenticationManagerBuilder ) throws Exception {
authenticationManagerBuilder.authenticationProvider( authenticationProvider() );
}
#Bean
public JdbcDaoImpl jdbcDao() {
JdbcDaoImpl jdbcDao = new JdbcDaoImpl();
jdbcDao.setDataSource( dataSource() );
return jdbcDao;
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
final DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService( jdbcDao() );
authenticationProvider.setPasswordEncoder( encoder() );
return authenticationProvider;
}
#Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder( 11 );
}
#Bean( name = "myDS")
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName( "com.mysql.cj.jdbc.Driver" );
dataSource.setUrl( "jdbc:mysql://localhost:3306/java_spring_angular_rest_security_acl2" );
dataSource.setUsername( "root" );
dataSource.setPassword( "alphax" );
return dataSource;
}
#Bean
public EhCacheBasedAclCache aclCache() {
return new EhCacheBasedAclCache(aclEhCacheFactoryBean().getObject(), permissionGrantingStrategy(), aclAuthorizationStrategy());
}
#Bean
public EhCacheFactoryBean aclEhCacheFactoryBean() {
EhCacheFactoryBean ehCacheFactoryBean = new EhCacheFactoryBean();
ehCacheFactoryBean.setCacheManager(aclCacheManager().getObject());
ehCacheFactoryBean.setCacheName("aclCache");
return ehCacheFactoryBean;
}
#Bean
public EhCacheManagerFactoryBean aclCacheManager() {
return new EhCacheManagerFactoryBean();
}
#Bean
public LookupStrategy lookupStrategy() {
return new BasicLookupStrategy(dataSource(), aclCache(), aclAuthorizationStrategy(), permissionGrantingStrategy());
}
#Bean
public AclAuthorizationStrategy aclAuthorizationStrategy() {
return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_ADMIN"));
}
#Bean
public PermissionGrantingStrategy permissionGrantingStrategy() {
return new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger());
}
#Bean( name = "defaultMethodSecurityExpressionHandler")
public MethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
AclPermissionEvaluator permissionEvaluator = new AclPermissionEvaluator(aclService());
expressionHandler.setPermissionEvaluator(permissionEvaluator);
expressionHandler.setPermissionCacheOptimizer( new AclPermissionCacheOptimizer( aclService() ) );
return expressionHandler;
}
#Bean( name = "myAclService")
public JdbcMutableAclService aclService() {
JdbcMutableAclService jdbcMutableAclService = new JdbcMutableAclService(dataSource(), lookupStrategy(), aclCache());
jdbcMutableAclService.setClassIdentityQuery( "SELECT ##IDENTITY" );
jdbcMutableAclService.setSidIdentityQuery( "SELECT ##IDENTITY" );
return jdbcMutableAclService;
}
}
and here is the pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.fireduptech.spring.rest</groupId>
<artifactId>hero</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>hero</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-acl -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-acl</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.0.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache-core -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.11</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Hope that helps someone :)
I have a problem. I'm using Spring4 and i want to add a configuration to be able to use spring data couchbase and i have an error :
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: file
[/home/charlie/Desktop/Ultimate
Projects/novare_dashboard/novare-project-dashboard/target/classes/hk/com/novare/dashboard/configuration/CouchbaseConfig.class];
nested exception is java.lang.annotation.AnnotationFormatError:
Invalid default: public abstract java.lang.Class
org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories.repositoryBaseClass()
at
org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.findCandidateComponents(ClassPathScanningCandidateComponentProvider.java:303)
Here is my code:
CouchbaseConfig.java
#Configuration
#EnableCouchbaseRepositories
public class CouchbaseConfig extends AbstractCouchbaseConfiguration{
#Override
protected List<String> bootstrapHosts() {
return Collections.singletonList("localhost");
}
#Override
protected String getBucketName() {
return "crud";
}
#Override
protected String getBucketPassword() {
return "password";
}}
WebMvcConfig.java
#Configuration
#EnableWebMvc
#ComponentScan(basePackageClasses = Application.class)
public class WebMvcConfig extends WebMvcConfigurerAdapter {
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean
public InternalResourceViewResolver jspViewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setPrefix("/WEB-INF/views/");
bean.setSuffix(".jsp");
return bean;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/WEB-INF/static/");
}}
POM.XML
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--H2-->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!--couchbase-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-couchbase</artifactId>
<version>1.4.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.couchbase.client</groupId>
<artifactId>couchbase-client</artifactId>
<version>1.4.9</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.0</version>
</dependency>
<!--JSON-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Can see the error for missing repositoryBaseClass config which is needed to create the repository proxies for your CouchbaseConfig class :-
nested exception is java.lang.annotation.AnnotationFormatError: Invalid default: public abstract java.lang.Class
org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories.repositoryBaseClass() at
Pls specify same as parameter to #EnableCouchbaseRepositories
I just found a solution regarding my error. You must change your spring-data-couchbase version to 1.2.2 and remove the annotation #Repository to your repository.