Configuring Ehcache - CacheManager must not be null - java

I tried to configure EhCache programmatically, but I have some problems... Firstly, I tried to use the newest version, where I just created config class with just one method and then I get the error java.lang.ClassNotFoundException: com.google.common.cache.CacheBuilderSpec.
I tried with lower version, which is 2.10.4, which is already in Spring Boot, but now I'm getting an error that CacheManager must not be null and I have no idea what is the problem... Probably I'm missing something, but I don't know what...
Current code with Ehcache 2.X:
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.CacheResolver;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.cache.interceptor.SimpleCacheErrorHandler;
import org.springframework.cache.interceptor.SimpleCacheResolver;
import org.springframework.cache.interceptor.SimpleKeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import net.sf.ehcache.config.CacheConfiguration;
#Configuration
#EnableCaching
public class EhCacheConfiguration implements CachingConfigurer {
#Bean(destroyMethod = "shutdown")
public net.sf.ehcache.CacheManager ehCacheManager() {
CacheConfiguration cacheConfiguration = new CacheConfiguration();
cacheConfiguration.setName("myCacheName");
cacheConfiguration.setMemoryStoreEvictionPolicy("LRU");
cacheConfiguration.setMaxEntriesLocalHeap(1000);
net.sf.ehcache.config.Configuration config = new net.sf.ehcache.config.Configuration();
config.addCache(cacheConfiguration);
return net.sf.ehcache.CacheManager.newInstance(config);
}
#Bean
#Override
public CacheManager cacheManager() {
return new EhCacheCacheManager(ehCacheManager());
}
#Bean
#Override
public KeyGenerator keyGenerator() {
return new SimpleKeyGenerator();
}
#Bean
#Override
public CacheResolver cacheResolver() {
return new SimpleCacheResolver();
}
#Bean
#Override
public CacheErrorHandler errorHandler() {
return new SimpleCacheErrorHandler();
}
}
Previous version of code with Ehcache 3.X:
import static org.ehcache.config.builders.CacheConfigurationBuilder.newCacheConfigurationBuilder;
import static org.ehcache.config.builders.CacheManagerBuilder.newCacheManagerBuilder;
import static org.ehcache.config.builders.ResourcePoolsBuilder.newResourcePoolsBuilder;
import java.util.concurrent.TimeUnit;
import org.ehcache.CacheManager;
import org.ehcache.config.units.EntryUnit;
import org.ehcache.config.units.MemoryUnit;
import org.ehcache.expiry.Duration;
import org.ehcache.expiry.Expirations;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
#EnableCaching
public class EhCacheConfiguration {
private static final Logger log = LoggerFactory.getLogger(EhCacheConfiguration.class);
#Bean
public CacheManager ehCacheManager() {
log.info("Creating cache manager programmatically");
try (CacheManager cacheManager = newCacheManagerBuilder()
.withCache("sessionCache",
newCacheConfigurationBuilder(Long.class, String.class,
newResourcePoolsBuilder().heap(2000, EntryUnit.ENTRIES).offheap(1, MemoryUnit.GB))
.withExpiry(Expirations.timeToLiveExpiration(Duration.of(30, TimeUnit.MINUTES)))
.withExpiry(Expirations.timeToIdleExpiration(Duration.of(5, TimeUnit.MINUTES))))
.build(true)) {
return cacheManager;
}
}
The class is in the subpackage of package where is the MyApplication class.
MyApplication class:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.web.WebApplicationInitializer;
#SpringBootApplication
#EnableJpaRepositories
public class MyApplication extends SpringBootServletInitializer implements WebApplicationInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MyApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Application is using Spring Boot and is running on WebLogic server...
Edit:
Added pom.xml:
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<groupId>com.app.lui.serviceweb</groupId>
<artifactId>lui-serviceWeb</artifactId>
<packaging>war</packaging>
<name>lui-serviceWeb</name>
<description>Lui Project</description>
<dependencies>
<dependency>
<groupId>com.app.lui.drools</groupId>
<artifactId>lui-drools</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</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.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- Apache CXF -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.1.11</version>
</dependency>
<!-- DB -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- Ehcache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
</dependencies>
<build>
<finalName>lui-serviceWeb</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<archive>
<manifest>
<addDefaultImplementationEntries>false</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
EDIT 2:
Added project:
Ehcache project
Logs:
Ehcache 2.X stack trace
Ehcache 3.X stack trace

You need the cacheResolver to know the cacheManager.
So, in your current code, just replace the cacheResolver bean with:
#Bean
#Override
public CacheResolver cacheResolver() {
return new SimpleCacheResolver(cacheManager());
}
And it is done. Might be the same for EhCache 3.X but I didn't test it.
Hope it helps.

We will need a fully working project to answer wit certainty. Right now, I tried your code and had to hack around to make it compile. CacheBuilderSpec is indeed a guava thing. So it seems Spring is picking Guava as its cache implementation, not Ehcache.
You might want to debug CacheAutoConfiguration and GuavaCacheConfiguration. The latter will be initialized at some point by Spring.

Related

WebApplicationInitializer not working after upgrading spring-boot-starter-parent

My code used to works well before I upgraded spring-boot-starter-parent from 1.0.2.RELEASE to 2.1.0.RELEASE.
When the version of spring-boot-starter-parent is 1.0.2.RELEASE, I could deploy this project to tomcat, run tomcat, and when I type localhost:8080/greeting.html on my browser I could see 'Hello World".
But after I upgrade the version to 2.1.0.RELEASE and do the same thing, I just got a 404 not found error.
QUESTION: How can I fix this problem with version 2.1.0.RELEASE of spring-boot-starter-parent?
Here is my code snippet and the pom file:
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.pluralsight</groupId>
<artifactId>event-tracker</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>event-tracker</name>
<description>An app to track our Events</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<!--<version>1.0.2.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-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
WebConfig:
package com.pluralsight;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.pluralsight")
public class WebConfig {
}
WebAppInitializer:
package com.pluralsight;
import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class WebAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("*.html");
}
private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation("com.pluralsight.WebConfig");
return context;
}
}
HelloController:
package com.pluralsight.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class HelloController {
#RequestMapping(value = "/greeting")
public String sayHello(Model model) {
model.addAttribute("greeting", "Hello World");
return "hello.jsp";
}
}
You can follow this link
Instead of WebAppInitializer class write Application class as in above link and declare start-class tag in properties.
It should work.

Unable to override spring security default basic authentication of rest API

I am new to spring environment and was trying my hand at spring security, but I am unable to achieve basic authentication.
When I add spring security starter to maven dependencies I get default basic authentication by spring with user = user & password generated when you run the app. So far this works fine.
But now even though I have added SecurityConfiguration the default behaviour doesn't go away. If I try to access the resource through my new credentials I get Bad credentials message.
I am stuck here as for why spring still uses the default configuration, as with all the tutorials I have followed this works fine.
Referenced Tutorials
https://www.youtube.com/watch?v=rOnoKiH97Nc
https://www.youtube.com/watch?v=kiIMCzEN3c0
https://www.youtube.com/watch?v=3s2lSD50-JI
pom.xml
<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.worldline.in</groupId>
<artifactId>maven_springboot_rest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>maven_springboot_rest</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
</project>
Application.java
package com.worldline.rest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
// Tried component scan too -----
// https://stackoverflow.com/questions/38072517/unable-to-override-spring-boots-default-security-configuration
//#ComponentScan({"com.worldline.config"})
//some stackoverflow links suggest to exclude it for default behavior to go away
//#SpringBootApplication (exclude = {SecurityAutoConfiguration.class })
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Rest Controller
package com.worldline.rest;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.worldline.pojo.Greeting;
#RestController
public class GreetingController {
private final AtomicLong counter = new AtomicLong();
#RequestMapping("/greeting")
public Greeting greeting(#RequestParam(value="name", defaultValue = "world") String name )
{
return new Greeting(counter.incrementAndGet(), name);
}
}
Security Configuration
package com.worldline.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
/*http.authorizeRequests()
.anyRequest()
.fullyAuthenticated()
.and().httpBasic();
http.csrf().disable();*/
http.authorizeRequests()
.antMatchers("/greeting").hasRole("ADMIN");
}
/*#Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().withUser("sunny").password("admin").roles("admin");
}
*/
#Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception
{
auth.inMemoryAuthentication().withUser("sunny").password("admin").roles("ADMIN");
}
}

springboot + angular2 deployment

I am trying to deploy my spring boot with angular 2 code to a war package
My springboot code contains JWT Spring security,
The problem is when I integrate and run in tomcat server. I am getting:
Whitelabel Error Page This application has no explicit mapping for
/error, so you are seeing this as a fallback.
Thu Mar 01 18:26:53 IST 2018 There was an unexpected error (type=Not
Found, status=404). No message available
But if i remove my spring security and integrate both together then it is working fine.
I don't know what is the problem with spring JWT security, So please, if anybody knows this issue, help me out
Web Security:
package com.boot.hms.security;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
#CrossOrigin
#EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
private UserDetailsService userDetailsService;
private BCryptPasswordEncoder bCryptPasswordEncoder;
public WebSecurity(UserDetailsService userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) {
this.userDetailsService = userDetailsService;
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
AuthenticationFilter authenticationFilter = new AuthenticationFilter(authenticationManager());
authenticationFilter.setFilterProcessesUrl("/hms/auth");
http .cors().and().csrf().disable().authorizeRequests().antMatchers("/hms/fetchmeta/*", "/hms/registration/*").permitAll()
.anyRequest().authenticated().and().addFilter(authenticationFilter)
.addFilter(new AuthorizationFilter(authenticationManager()))
// this disables session creation on Spring Security
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
System.out.println("<....Web Security......>");
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
return source;
}
}
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.boot</groupId>
<artifactId>hms</artifactId>
<version>1</version>
<packaging>war</packaging>
<name>version</name>
<description>Hospital Management System</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<start-class>com.programmer.gate.HmsApplication</start-class>
</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-mail</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-web</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>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<directory>D:\hmsDeployment\dist</directory>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
</project>
Main class:
package com.boot.hms;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.boot.hms.security.WebSecurity;
#CrossOrigin
#Import(WebSecurity.class)
#SpringBootApplication
#ComponentScan(basePackages="com.boot.hms")
public class HmsApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(HmsApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(HmsApplication.class, args);
}
#Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
Property file:
#Database
spring.datasource.url= jdbc:mysql://192.168.12.112:3306/hms
spring.datasource.username=root
spring.datasource.password=root
#Server
#server.contextPath=/hms
#server.port = 8080
#JPA
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.autoconfigure.exclude=SecurityAutoConfiguration
#security.user.name=admin
#security.user.password=admin
security.basic.enabled=false
spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false
spring.jackson.deserialization.accept-empty-string-as-null-object=true
Solution
You are probably seeing this error because of your custom security configuration class (WebSecurity)
You did not explicitly declared a "Free for all" rule for the base url, / (were the Angular app will live!). Here I am assuming the base url is /, if not adapt this answer to be used with your base real url.
So, in your WebSecurity add the mentioned rule by changing this:
//...omitted code for brevity
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers("/hms/fetchmeta/*", "/hms/registration/*").permitAll()
//...omitted code for brevity
to
//...omitted code for brevity
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers("/hms/fetchmeta/*", "/hms/registration/*", "/") // <--Notice here the base url added to the "free for all" rule!
.permitAll()
//...omitted code for brevity
But ... Why this error happen?!
Well, as you commented, the explicit error is
Whitelabel Error Page This application has no explicit mapping for
/error, so you are seeing this as a fallback. Fri Mar 02 13:38:44 IST
2018 There was an unexpected error (type=Forbidden, status=403).
Access Denied
This mean when you try to access the Angular app (located from the server point of view at the base url, /, for instance), the server detect that you're not logged in, so it throws a 403 Forbidden. This would normally be shown in an error page in a Spring Boot application... and since you do not have a mapping for this route, /error, (neither you have the file under src/main/resources/static/error/403.html which would normally show this error), then you see this "fallback" message you showed me.
Recommendation
Since now the base url / is free for all, your services (provided by Spring Boot) should be prefixed with something like /api or any similar in order to prevent free access to them.
Reference
If you want to have a reference, check this Security Config, which does exactly what you're trying to do (it belongs to a project which deploy a Spring Boot + Angular packed as war project)

Can't get any unit tests to run in Spring Boot

I'm trying to write a simple unit test. This test function will call my service, which grabs info from the database, pushes it to a list and returns it. I've looked high and low in the debug logs to find what could be causing, but it seems nothing on the web is helping me out. I'm not too familiar with Spring Boot, but it seems surprising that all this effort and I am unable to get a simple unit test to pass.
Error Logs
http://text-share.com/view/fb0369c3
Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed;
Example Test
package com.algoq.algoq;
import com.algoq.algoq.models.Subscriber;
import com.algoq.algoq.respositories.SubscriberRepository;
import com.algoq.algoq.services.AlgorithmService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import static org.assertj.core.api.Assertions.assertThat;
#RunWith(SpringRunner.class)
#TestConfiguration
#SpringBootTest(classes = {
AlgoQApplication.class,
})
public class ExampleTest extends AlgoQApplicationTests {
#Autowired
private AlgorithmService aService;
#MockBean
private SubscriberRepository employeeRepository;
#Bean
public AlgorithmService aService() {
return new AlgorithmService();
}
#Test
public void subscriberListNull() throws Exception {
ArrayList<Subscriber> subs = aService.getSubscribers();
assertThat(subs).isEmpty();
}
}
Service
package com.algoq.algoq.services;
import com.algoq.algoq.models.Subscriber;
import com.algoq.algoq.respositories.SubscriberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
#Service
public class AlgorithmService {
#Autowired
private SubscriberRepository subRep;
/**
* Gets a list of subscribers to return to the API
* #return
*/
public ArrayList<Subscriber> getSubscribers() {
ArrayList<Subscriber> subscribers = new ArrayList<>();
subRep.findAll()
.forEach(subscribers::add);
return subscribers;
}
/**
* Adds a new subscriber to the database
* #param sub
* #return
*/
public void addSubscriber(Subscriber sub) {
subRep.save(sub);
}
/**
* Finds a single user id
* #param email
* #return
*/
public List<Subscriber> getSubscriber(String email) {
return subRep.findByEmailAddress(email);
}
}
Application
package com.algoq.algoq;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
#SpringBootApplication
//#EnableScheduling
public class AlgoQApplication {
public static void main(String[] args) {
SpringApplication.run(AlgoQApplication.class, args);
}
}
POM
<?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.algoQ</groupId>
<artifactId>algo-q</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>algo-q</name>
<description>An algorithm a day keeps the brain up to date</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-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.12</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>2.5.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>1.5.2.RELEASE</version>
</dependency>
<!--<dependency>-->
<!--<groupId>com.h2database</groupId>-->
<!--<artifactId>h2</artifactId>-->
<!--<version>1.4.194</version>-->
<!--</dependency>-->
<dependency>
<groupId>org.pygments</groupId>
<artifactId>pygments</artifactId>
<version>1.5</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
The real cause of the exception is
java.lang.ClassNotFoundException: javax.xml.bind.JAXBException
So I believe you need to add JAXBE library to your classpath (it was removed from JDK in java9 and I guess you are using java9)
Try to add this to your pom file
<!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
JDK
/Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home/bin/java
pom.xml
1.8
Are you using java 8 or 9 ?
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'entityManagerFactory' defined in class path
resource
[org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]:
Invocation of init method failed; nested exception is
java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
Issue with java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException ,
Run the application with Java 8 environement or Include the JAXB library for Java 9, JAXB API are not included in JAVA SE 9. Refer Deprecated, for removal: This API element is subject to removal in a future version.. Use --add-modules ( --add-modules java.xml.bind ) to add module in classpath. Jave has only deprecated and does not add javax.xml.bind module on classpath by default.
Otherwise include as dependency through maven.
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>

Spring 4.3.5 annotation based configuration tomcat-8 404 in eclipse neon 2

I have tried lot of time the same project to develop spring 4 based web app, but i am able to a project single time. I don't understand where i am making mistake. I have taken lot of references for my first Spring 4 annotation based first web application and i have followed each step by step. But all the time i failed. No i am here to understand where i am making mistake.
Please friend review and let me know the issue.
Efforts
Firstly i have create maven project and used maven-archtypes-webapp and specify group-ip, packages and so on.
Then, i have add dependencies and plugin, here is my pom.xml file.
<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.org.spring4</groupId>
<artifactId>FirstApp</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>FirstApp Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<build>
<finalName>firstapp</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warSourceDirectory>src/main/webapp/</warSourceDirectory>
<warName>firstapp</warName>
</configuration>
</plugin>
</plugins>
</build>
</project>
Then i have created annotation based configuration as mentioned on http://websystique.com/ this website. i have not created [it’s the preferred way] class, instead i have used first two classes.
here are both configuration classes:
AppConfig.java
package com.org.spring.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;
import org.springframework.web.servlet.view.JstlView;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.org.spring")
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;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
and AppInitializer.java
package com.org.spring.config;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class AppInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(AppConfig.class);
ctx.setServletContext(container);
ServletRegistration.Dynamic servlet = container.addServlet("dispatcher", new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
}
}
after that i have created my controller as,
package com.org.spring.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class HelloController {
#GetMapping("/hello")
public String hello(Model model) {
model.addAttribute("name", "John Doe");
return "welcome";
}
}
then, i have created welcome.jsp file in WEB-INF/views directory as per my configuration.
When i tried to run this project on my tomcat 8 it gives me 404 error always. I don't know why i am getting this error.
Please friend help me.
change #Controller to #RestController and add #RequestMapping to your class in order to access to your api
localhost:port/uri/apimapping/hello

Categories