I´m trying to execute an app using spring boot but I got the following error message:"Circular view path [index]: would dispatch back to the current handler URL [/test/index] again". I already see some similar post but I didn't have success.
Below you can see the error message:
Circular view path [index]: would dispatch back to the current handler URL [/test/index] again
build.gradle
buildscript {
repositories {
mavenCentral()
maven { url "http://repo.spring.io/snapshot" }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.1.BUILD-SNAPSHOT")
}
}
apply plugin: 'java'
apply plugin: 'eclipse-wtp'
apply plugin: 'spring-boot'
apply plugin: 'war'
repositories {
maven { url "http://repo.spring.io/snapshot" }
maven { url "http://repo.spring.io/milestone" }
mavenCentral()
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
compile 'org.springframework:spring-webmvc:3.2.2.RELEASE'
compile 'jstl:jstl:1.2'
providedRuntime 'org.apache.tomcat.embed:tomcat-embed-jasper'
}
WebMvcConfig.java
package com.hellomvc.test.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
#EnableWebMvc
#Configuration
class WebMvcConfig extends WebMvcConfigurerAdapter {
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("WEB-INF/pages/");
resolver.setSuffix(".jsp");
resolver.setCache(false);
resolver.setOrder(2);
return resolver;
}
}
AppInitializer
package com.hellomvc.test.initializer;
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;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
public class AppInitializer implements WebApplicationInitializer {
private static final String CONFIG_LOCATION = "com.hellomvc.test.config";
private static final String MAPPING_URL = "/";
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping(MAPPING_URL);
}
private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation(CONFIG_LOCATION);
return context;
}
}
Controller:
package com.hellomvc.test.controller;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
#RestController
#Configuration
#ComponentScan("com.hello.spring.example.controller")
#EnableAutoConfiguration
public class HelloController {
#RequestMapping(value = "/test/{name}", method = RequestMethod.GET)
public ModelAndView welcome(#PathVariable("name") String name) {
ModelAndView model = new ModelAndView();
model.setViewName("index");
model.addObject("name", name);
return model;
}
public static void main(String[] args) {enter code here
SpringApplication.run(HelloController.class, args);
}
}
Thanks for your help.
Edgardo
Related
I am trying to use spring-boot and gradle to create a simple CRUD application as a PoC. At this point, I am getting this error when I am attempting to load the front website-
2019-02-11 14:54:48.915 WARN 5704 --- [nio-8080-exec-3] o.s.web.servlet.PageNotFound : No mapping for GET /WEB-INF/jsp/welcome.jsp
I am using spring boot and gradle by specifying in the controller class, and the application properties and build gradle script but still I get this debug statement when I go to my welcome.jsp and the now corresponding 404 error.
I've already looked through a lot of tutorials, but a lot of them are in maven. At this point, I know I need to specify the path in the controller and specify the resources in the properties and build scripts. I have even tried creating a specific mvcconfiguration but I don't think I need one.
build.gradle
buildscript {
ext {
springBootVersion = '2.1.2.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}}
apply plugin: 'eclipse'
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.bill'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/milestone' }
}
ext {
set('springCloudServicesVersion', '2.1.0.RELEASE')
set('springCloudVersion', 'Greenwich.RELEASE')
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-actuator'
/*implementation 'io.pivotal.spring.cloud:spring-cloud-services-starter-config-client'
/*implementation 'io.pivotal.spring.cloud:spring-cloud-services-starter-service-registry'
implementation 'org.springframework.cloud:spring-cloud-starter'
/*implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-ribbon'
*/
runtimeOnly 'mysql:mysql-connector-java'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
dependencyManagement {
imports {
mavenBom "io.pivotal.spring.cloud:spring-cloud-services-dependencies:${springCloudServicesVersion}"
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
application.properties
spring.mvc.view.prefix:/WEB-INF/jsp/
spring.mvc.view.suffix:.jsp
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/mh1
spring.datasource.username=root
spring.datasource.password=root
MainController.java
package com.javainuse;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.javainuse.BankAccountApplication;
import com.javainuse.User;
import com.javainuse.UserDAO;
import com.javainuse.UserForm;
#Controller
public class MainController {
#Autowired
UserDAO userDAO;
#RequestMapping("/welcome")
public ModelAndView viewHome() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("welcome");
return modelAndView;
}
#RequestMapping("/users")
public String viewUsers(Model model) {
List<User> list = UserDAO.getUsers();
model.addAttribute("users", list);
return "usersPage";
}
#RequestMapping("/registerSuccessful")
public String viewRegisterSuccessful() {
return "registerSuccessfulPage";
}
#RequestMapping(value = "/register", method = RequestMethod.GET)
public String viewRegister(Model model) {
UserForm form = new UserForm();
model.addAttribute("userForm", form);
return "registerPage";
}
public String saveRegister( Model model, //
#ModelAttribute("userForm") #Validated UserForm userForm, //
BindingResult result, //
final RedirectAttributes redirectAttributes) {
// Validate result
if (result.hasErrors()) {
return "registerPage";
}
User newUser= null;
try {
newUser = userDAO.createUser(userForm);
}
// Other error!!
catch (Exception e) {
model.addAttribute("errorMessage", "Error: " + e.getMessage());
return "registerPage";
}
redirectAttributes.addFlashAttribute("newUser", newUser);
return "redirect:/registerSuccessful";
}
}
MvcConfiguration.java
package com.javainuse;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#ComponentScan(basePackages="...package name...")
#EnableWebMvc
public class MvcConfiguration extends WebMvcConfigurerAdapter{
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
2019-02-11 14:54:48.915 WARN 5704 --- [nio-8080-exec-3] o.s.web.servlet.PageNotFound : No mapping for GET /WEB-INF/jsp/welcome.jsp
I am trying to run a standalone MVC + JPA application with embedded tomcat
But the application fails with the following error, tho I dont see any obvious reason for this failure. I believe this has something to do with the way Tomcat deals with class loaders
I am not sure how spring boot gets around this problem
Appreciate if anyone can shed light on why this error is thrown
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepositoryImpl': Initialization of bean failed; nested exception is java.lang.IllegalAccessError: class com.acme.$Proxy53 cannot access its superinterface com.acme.UserRepository
... 36 more
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:584)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:846)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:863)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:400)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:291)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4661)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5131)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1382)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1372)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:907)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:831)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1382)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1372)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:907)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:423)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:933)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:398)
at com.acme.EmbeddedTomcatWebAppWithoutBoot.main(EmbeddedTomcatWebAppWithoutBoot.java:65)
Caused by: java.lang.IllegalAccessError: class com.acme.$Proxy53 cannot access its superinterface com.acme.UserRepository
at java.lang.reflect.Proxy.defineClass0(Native Method)
at java.lang.reflect.Proxy.access$300(Proxy.java:228)
at java.lang.reflect.Proxy$ProxyClassFactory.apply(Proxy.java:642)
at java.lang.reflect.Proxy$ProxyClassFactory.apply(Proxy.java:557)
at java.lang.reflect.WeakCache$Factory.get(WeakCache.java:230)
at java.lang.reflect.WeakCache.get(WeakCache.java:127)
at java.lang.reflect.Proxy.getProxyClass0(Proxy.java:419)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:719)
at org.springframework.aop.framework.JdkDynamicAopProxy.getProxy(JdkDynamicAopProxy.java:123)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:110)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:473)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:352)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:301)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:434)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1749)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:576)
... 36 more
Sources used
EmbeddedTomcatWebAppWithoutBoot.java
package com.acme;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.apache.catalina.Container;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.repository.config.RepositoryConfiguration;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.SharedEntityManagerCreator;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;
import javax.sql.DataSource;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import static java.lang.String.valueOf;
public class EmbeddedTomcatWebAppWithoutBoot {
private static final int PORT = 8080;
public static void main(String[] args) throws LifecycleException {
String appBase = ".";
Tomcat tomcat = new Tomcat();
tomcat.setBaseDir(createTempDir());
tomcat.setPort(PORT);
tomcat.getHost().setAppBase(appBase);
tomcat.addWebapp("", ".");
tomcat.getConnector(); // Trigger the creation of the default connector
tomcat.start();
ClassLoader classLoader = findContext(tomcat).getLoader().getClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
tomcat.getServer().await();
}
private static Context findContext(Tomcat tomcat) {
for (Container child : tomcat.getHost().findChildren()) {
if (child instanceof Context) {
return (Context) child;
}
}
throw new IllegalStateException("The host does not contain a Context");
}
// based on AbstractEmbeddedServletContainerFactory
private static String createTempDir() {
try {
File tempDir = File.createTempFile("tomcat.", "." + PORT);
tempDir.delete();
tempDir.mkdir();
tempDir.deleteOnExit();
return tempDir.getAbsolutePath();
} catch (IOException ex) {
throw new RuntimeException(
"Unable to create tempDir. java.io.tmpdir is set to " + System.getProperty("java.io.tmpdir"),
ex
);
}
}
}
class MainWebAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(DataAccessConfiguration.class, UserRepositoryImpl.class);
servletContext.addListener(new ContextLoaderListener(rootContext));
AnnotationConfigWebApplicationContext servletAppContext = new AnnotationConfigWebApplicationContext();
servletAppContext.register(WebMvcConfiguration.class);
DispatcherServlet dispatcherServlet = new DispatcherServlet(servletAppContext);
ServletRegistration.Dynamic servletRegistration = servletContext.addServlet("dispatcher", dispatcherServlet);
servletRegistration.setLoadOnStartup(1);
servletRegistration.addMapping("/");
}
}
#EnableWebMvc
#Configuration
#Import(UserResource.class)
class WebMvcConfiguration {}
#RestController
class UserResource {
private final UserRepository userRepository;
public UserResource(UserRepository userRepository) {
this.userRepository = userRepository;
}
#GetMapping
ResponseEntity<List<User>> get() {
return ResponseEntity.ok().body(userRepository.findAllUsers());
}
}
#Getter
#Setter
#Builder
#NoArgsConstructor
#AllArgsConstructor
class UserRequest {
private String name;
private String authorityName;
}
#Configuration
#EnableTransactionManagement
class DataAccessConfiguration {
#Bean
DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.setName("sample")
.build();
}
#Bean
LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(dataSource);
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
factoryBean.setJpaVendorAdapter(vendorAdapter);
factoryBean.setPackagesToScan(EmbeddedTomcatWebAppWithoutBoot.class.getPackage().getName());
// set som extra properties hibernate
Properties jpaProperties = new Properties();
jpaProperties.setProperty("hibernate.show_sql", "true");
jpaProperties.setProperty("hibernate.format_sql", "true");
jpaProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
jpaProperties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
factoryBean.setJpaProperties(jpaProperties);
return factoryBean;
}
#Bean
JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
#Bean
EntityManager entityManager(EntityManagerFactory entityManagerFactory) {
return SharedEntityManagerCreator.createSharedEntityManager(entityManagerFactory);
}
#Bean
PersistenceExceptionTranslationPostProcessor postProcessor() {
return new PersistenceExceptionTranslationPostProcessor();
}
}
interface UserRepository {
List<User> findAllUsers();
}
#Repository
#Transactional
class UserRepositoryImpl implements UserRepository {
private final EntityManager entityManager;
public UserRepositoryImpl(EntityManager entityManager) {
this.entityManager = entityManager;
}
#Override
public List<User> findAllUsers() {
return entityManager.createQuery("from User", User.class)
.getResultList();
}
}
#Entity
#Getter
#Setter
#Builder
#NoArgsConstructor
#AllArgsConstructor
#ToString
class User {
#Id
#GeneratedValue
private int id;
private String name;
}
build.gradle
ext {
set('spring-boot.version', '2.1.2.RELEASE')
// copied from above
set('spring.version', '5.1.4.RELEASE')
// async logging
set('lmax-disruptor.version', '3.4.2')
// misc utils
set('unexceptional.version', '1.0.0')
set('mapstruct.version', '1.3.0.Final')
// tooling
set('jetbrains-annotations.version', '16.0.2')
}
group 'com.acme'
version '1.0.0-SNAPSHOT'
apply plugin: 'java-library'
sourceCompatibility = 1.8
repositories {
mavenCentral()
jcenter()
maven {
url 'https://repo.spring.io/libs-milestone'
}
}
configurations {
springBom
developmentOnly
// we want to make sure the dependencies bom ia available everywhere so that the dependencies can be resolved across all configurations
compileOnly.extendsFrom(springBom)
annotationProcessor.extendsFrom(springBom)
testAnnotationProcessor.extendsFrom(springBom)
api.extendsFrom(springBom)
implementation.extendsFrom(springBom)
runtimeClasspath {
extendsFrom developmentOnly
}
// lets inherit everything
testCompileOnly.extendsFrom(compileOnly)
}
dependencies {
//*** bill of materials
springBom platform("org.springframework.boot:spring-boot-dependencies:${project.'spring-boot.version'}")
implementation 'org.springframework:spring-context'
implementation 'org.springframework.data:spring-data-jpa'
implementation 'org.hibernate:hibernate-core'
implementation 'com.h2database:h2'
// web
implementation 'org.springframework:spring-web'
implementation 'org.springframework:spring-webmvc'
// jackson for json serialization
implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8' // new java 8 classes like stream, OPtional
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310' // new java date & time api
implementation 'com.fasterxml.jackson.module:jackson-module-parameter-names' // custom modules within jackson
// embedded server
implementation 'org.apache.tomcat.embed:tomcat-embed-jasper'
// log4j2
implementation 'org.apache.logging.log4j:log4j-core'
implementation 'org.apache.logging.log4j:log4j-slf4j-impl'
implementation 'org.apache.logging.log4j:log4j-jcl'
implementation 'org.apache.logging.log4j:log4j-jul'
implementation "com.lmax:disruptor:${project.'lmax-disruptor.version'}"
// unexceptional for making sure code is not super polluted
implementation "io.earcam:io.earcam.unexceptional:${project.'unexceptional.version'}"
// junit
testImplementation 'org.junit.jupiter:junit-jupiter-api'
testImplementation 'org.junit.jupiter:junit-jupiter-engine'
testImplementation 'org.junit.jupiter:junit-jupiter-params'
testImplementation 'org.mockito:mockito-junit-jupiter'
// test misc
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.hamcrest:hamcrest-library'
testImplementation 'org.mockito:mockito-junit-jupiter'
// NOTE: Due to a bug as of now mapstruct needs to go before lombok
// https://github.com/mapstruct/mapstruct/issues/1581
// maspstruct
implementation "org.mapstruct:mapstruct:${project.'mapstruct.version'}"
implementation "org.mapstruct:mapstruct:${project.'mapstruct.version'}"
annotationProcessor "org.mapstruct:mapstruct-processor:${project.'mapstruct.version'}"
testAnnotationProcessor "org.mapstruct:mapstruct-processor:${project.'mapstruct.version'}"
// lombok
compileOnly('org.projectlombok:lombok')
annotationProcessor('org.projectlombok:lombok')
}
configurations {
all {
// we need to exclude logging to avoid keeping both slf4j & log4j2 both in the same location
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
// `spring-boot-starter-test` is pulling older version of junit. Lets just ignore it
exclude group: 'junit', module: 'junit'
}
}
The complete runnable gradle project can be be found here
The creation of the proxy is failing because the interface that defines the proxy's API, UserRepository, is package-private, access to a package-private type is prohibited across class loaders and the class loader being used to create the proxy is not the same as the class loader that was used to load UserRepository.
There are a few different ways that you can fix the problem, including:
Make UserRepository public
Update MainWebAppInitializer to call rootContext.setClassLoader(getClass().getClassLoader())
The second option is closer to what Spring Boot does and ensures that the class loader that loaded MainWebAppInitializer (and UserRepository) is used for proxy creation.
This is my first experience using Spring MVC with REST API for having an angular front end. I created 3 configuration files:
Here is my ApplicationConfig
package com.app.config;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import javax.persistence.EntityManagerFactory;
#SuppressWarnings("unused")
#EnableWebMvc
#Configuration
#ComponentScan("com.app.controller")
#EnableJpaRepositories("com.app.dao")
public class ApplicationConfig {
#Bean
public InternalResourceViewResolver setup() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Bean
public DataSource dataSource() {
System.out.println("in datasoure");
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/db");
dataSource.setUsername("root");
dataSource.setPassword("");
return dataSource;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("com.app.model");
factory.setDataSource(dataSource());
return factory;
}
#Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
}
MVC Config
package com.app.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#EnableWebMvc
#Configuration
public class MvcConfig implements WebMvcConfigurer {
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp("/WEB-INF/views/", ".jsp");
}
#Bean
public InternalResourceViewResolver setup() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
WebInitializer
package com.app.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { ApplicationConfig.class, MvcConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
I also created a controller :
package com.app.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.app.dao.AdminsRepository;
import com.app.model.Admin;
#SuppressWarnings("unused")
#Controller
public class AdminsController {
#Autowired
private AdminsRepository adminsRepository;
#GetMapping("/admins")
#ResponseBody
public String getAllAdmins(Model model) {
return adminsRepository.findAll().toString();
}
#GetMapping("/admin/{id}")
#ResponseBody
public String getAdmin(#PathVariable("id") int id, Model model) {
return adminsRepository.findById((long) id).orElse(null).toString();
}
#PostMapping("/admin")
#ResponseBody
public String createAdmin(Admin admin, Model model) {
System.out.println(admin);
return adminsRepository.save(admin).toString();
}
}
The repository :
package com.app.dao;
//import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.app.model.Admin;
#Repository
public interface AdminsRepository extends JpaRepository <Admin, Long>{ }
And my model :
package com.app.model;
import java.io.Serializable;
import javax.persistence.*;
import java.sql.Timestamp;
import java.util.List;
#Entity
#Table(name="admins")
#NamedQuery(name="Admin.findAll", query="SELECT a FROM Admin a")
public class Admin implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private int id;
#Column(name="created_at")
private Timestamp createdAt;
private String email;
private String login;
private String password;
private String name;
private String surname;
// ... getters and setters + delegated methods
}
When I start running the application and open the browser I receive an error message:
No qualifying bean of type 'com.app.dao.AdminsRepository' available:
expected at least 1 bean which qualifies as autowire candidate. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
G'day David,
Just breaking down the answer moiljter already gave you.
You can only #Autowire objects that are declared in packages being scanned for components.
Currently, your #ComponentScan annotation only includes your controller package:
#ComponentScan("com.app.controller")
Broaden the search slightly like so:
#ComponentScan("com.app")
Then it should pick up your AdminsRepository and hum nicely.
Cheers,
ALS
You need to add "com.app.dao" to the list of packages that Spring will scan for components (and maybe also "com.app.model" if any of those annotations are Spring ones), or just change it to scan "com.app" (which will include everything in your app.
I am new to Spring and trying to develop one small application using spring annotation with Maven. But I am getting **"The requested resource is not available."**I can understand that server is not able to locate the requested resource. But I am not able to resolve it, So please help me on this.
Below are my project structure and code:-
SpringRootConfig.java
package com.capp.config;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.ComponentScan;
#Configurable
#ComponentScan( basePackages = {"com.capp"})
public class SpringRootConfig {
}
package com.capp.config;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
#SuppressWarnings("deprecation")
#Configurable
#ComponentScan( basePackages = {"com.capp"})
#EnableWebMvc
public class SpringWebConfig extends WebMvcConfigurerAdapter {
public void addResourceHandlers(ResourceHandlerRegistry registry) {
}
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver vr =new InternalResourceViewResolver();
vr.setViewClass(JstlView.class);
vr.setPrefix("/WEB-INF/view/");
vr.setSuffix(".jsp");
return vr;
}
}
ContactAppDispatcherServletIntializer.java
package com.capp.config;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class ContactAppDispatcherServletIntializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {SpringRootConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
// TODO Auto-generated method stub
return new Class[] {SpringRootConfig.class};
}
#Override
protected String[] getServletMappings() {
// TODO Auto-generated method stub
return new String[] {"/"};
}
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
// TODO Auto-generated method stub
super.onStartup(servletContext);
}
}
TestController.java
package com.capp.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class TestController {
#RequestMapping(value="/test/hello")
public String helloWorld() {
return "hello";
}
}
When i am runing the application with http://localhost:8080/SpringContactApp/test/hello not able to find the hello.jsp which is under WEB-INF folder.
I presume the JSP is directly under the WEB-INF folder. If this is the case, create a subdirectory 'view' and move the JSP there.
In the view resolver, you set the prefix to "/WEB-INF/view/", your view resources must be in that location.
I'm trying to secure a REST API using Spring security 3.2.5 and a java based configuration.
Actually i've found many examples developed with an "old" xml approach, but nothing with a complete java configuration.
Where can i find some useful tutorial?
The project creates a REST API and some jsp usesd to allow the admin to populate an underlyin DB (Hibernate is used as ORM):
Here is my Config class:
package com.idk.fantappapaback.spring;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.tomcat.dbcp.dbcp.BasicDataSource; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; import org.springframework.orm.hibernate4.HibernateTransactionManager; import org.springframework.orm.hibernate4.LocalSessionFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.web.multipart.support.StandardServletMultipartResolver; import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.JstlView; import org.springframework.web.servlet.view.UrlBasedViewResolver;
import com.google.common.base.Preconditions; import com.idk.fantappapaback.spring.security.SecurityConfig;
#Configuration #EnableWebMvc #EnableTransactionManagement #PropertySource({ "classpath:persistence-mysql.properties" }) #ComponentScan({ "com.idk.fantappapaback.persistence","com.idk.fantappapaback.rest","com.idk.fantappapaback.spring.controllers","com.idk.fantappapaback.spring.security" }) #Import({ SecurityConfig.class }) public class BackEndConfig extends WebMvcConfigurerAdapter{
#Autowired
private Environment env;
public BackEndConfig() {
super();
}
//l'application context estrae il session factory da questo bean
#Bean
public LocalSessionFactoryBean sessionFactory() {
final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(restDataSource());
sessionFactory.setPackagesToScan(new String[] { "com.idk.fantappapaback.persistence.model" });
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public DataSource restDataSource() {
final BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
return dataSource;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(final SessionFactory sessionFactory) {
final HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory);
return txManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
final Properties hibernateProperties() {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
//***Proprieta per l'output delle query in sql che qui disabilito
// hibernateProperties.setProperty("hibernate.show_sql", "true");
// hibernateProperties.setProperty("hibernate.format_sql", "true");
// hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true");
return hibernateProperties;
}
#Bean
public UrlBasedViewResolver setupViewResolver() {
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setPrefix("WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean
public StandardServletMultipartResolver multipartResolver(){
return new StandardServletMultipartResolver();
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/"); // registry.addResourceHandler("/css/**") // .addResourceLocations("/css/"); // registry.addResourceHandler("/img/**") // .addResourceLocations("/img/");
registry.addResourceHandler("/js/**")
.addResourceLocations("/js/");
}
}
this is my very basic Security config that i use to have a form log in on the jsp views:
package com.idk.fantappapaback.spring.security;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; 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({ SecurityConfig.class }) nella BackEndConfig #Configuration #EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter{ #Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("masquenada").password("123456").roles("USER"); // auth.inMemoryAuthentication().withUser("masquenada").password("123456").roles("ADMIN"); auth.inMemoryAuthentication().withUser("masquenada").password("123456").roles("SUPERADMIN"); }
#Override protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() // .antMatchers("/players/**").access("hasRole('ROLE_USER')") .antMatchers("/createSeason/**").access("hasRole('ROLE_SUPERADMIN')") .and().formLogin().permitAll() .and().httpBasic();
} }
here is my SecurityWebApplicationInitializer :
package com.idk.fantappapaback.spring.security;
import org.springframework.security.web.context.*;
public class SecurityWebApplicationInitializer
extends AbstractSecurityWebApplicationInitializer {
}
The main question is : how to add the token based autorization?
I've added Spring oAuth 2 and Spring integration to my pom but i need some hint about introducing spring oAuth keeping the form login.
You need to "configure" your SecurityWebApplicatioInitializer.
http://spring.io/blog/2013/07/03/spring-security-java-config-preview-web-security/