Reputation: 175
the same war file that runs without issue locally fails with the following looping error:
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'customSuccessHandler': Error creating bean with name 'customSuccessHandler': Unsatisfied dependency expressed through field 'engineerService': Error creating bean with name 'engineerServiceImpl': Unsatisfied dependency expressed through field 'engineerRepository': Error creating bean with name 'engineerRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class mvc.domain.Engineer; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'engineerRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class mvc.domain.Engineer; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'engineerServiceImpl': Unsatisfied dependency expressed through field 'engineerRepository': Error creating bean with name 'engineerRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class mvc.domain.Engineer; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'engineerRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class mvc.domain.Engineer; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customSuccessHandler': Unsatisfied dependency expressed through field 'engineerService': Error creating bean with name 'engineerServiceImpl': Unsatisfied dependency expressed through field 'engineerRepository': Error creating bean with name 'engineerRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class mvc.domain.Engineer; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'engineerRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class mvc.domain.Engineer; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'engineerServiceImpl': Unsatisfied dependency expressed through field 'engineerRepository': Error creating bean with name 'engineerRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class mvc.domain.Engineer; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'engineerRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class mvc.domain.Engineer
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:137) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:535) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:369) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:313) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.web.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:150) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.web.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:130) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.web.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:86) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:169) [spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5303) [catalina.jar:8.0.43]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145) [catalina.jar:8.0.43]
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:753) [catalina.jar:8.0.43]
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:729) [catalina.jar:8.0.43]
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717) [catalina.jar:8.0.43]
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1092) [catalina.jar:8.0.43]
at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1834) [catalina.jar:8.0.43]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_121]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_121]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_121]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_121]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_121]
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'customSuccessHandler': Error creating bean with name 'customSuccessHandler': Unsatisfied dependency expressed through field 'engineerService': Error creating bean with name 'engineerServiceImpl': Unsatisfied dependency expressed through field 'engineerRepository': Error creating bean with name 'engineerRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class mvc.domain.Engineer; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'engineerRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class mvc.domain.Engineer; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'engineerServiceImpl': Unsatisfied dependency expressed through field 'engineerRepository': Error creating bean with name 'engineerRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class mvc.domain.Engineer; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'engineerRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class mvc.domain.Engineer; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customSuccessHandler': Unsatisfied dependency expressed through field 'engineerService': Error creating bean with name 'engineerServiceImpl': Unsatisfied dependency expressed through field 'engineerRepository': Error creating bean with name 'engineerRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class mvc.domain.Engineer; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'engineerRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class mvc.domain.Engineer; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'engineerServiceImpl': Unsatisfied dependency expressed through field 'engineerRepository': Error creating bean with name 'engineerRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class mvc.domain.Engineer; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'engineerRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class mvc.domain.Engineer
looks like our CustomSuccessHandler -> Autowires a @Service -> which in turn wires a repository made of a JPA entity. It seems that it does not like the JPA Entity. Where I'm stuck is that the same war file will load without error when run locally.
In the past I have been able to switch dependency versions in the pom and it will resolve the issue. this has been very flaky and I can't seem to find a repeatable pattern
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.astontech.timecards</groupId>
<artifactId>com.astontech.timecards</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
<!--<relativePath />-->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- ===================================================== -->
<!-- SPRING BOOT MODULES [DATA, WEB, SECURITY, TEST, REST] -->
<!-- ===================================================== -->
<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>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.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<scope>test</scope>
</dependency>
<!-- ============================================== -->
<!-- ============================================== -->
<!-- DATABASE DEPENDENCIES -->
<!-- ============================================== -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- ============================================== -->
<!-- ============================================== -->
<!-- TAG LIBRARIES [JSTL, JASPER, SPRING SECURITY] -->
<!-- ============================================== -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<!--<dependency>-->
<!--<groupId>org.springframework.security</groupId>-->
<!--<artifactId>spring-security-taglibs</artifactId>-->
<!--<version>4.0.3.RELEASE</version>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>org.springframework.security</groupId>-->
<!--<artifactId>spring-security-ldap</artifactId>-->
<!--<version>4.0.3.RELEASE</version>-->
<!--</dependency>-->
<dependency>
<groupId>org.springframework.security.extensions</groupId>
<artifactId>spring-security-saml2-core</artifactId>
<version>1.0.2.RELEASE</version>
</dependency>
<!--<dependency>-->
<!--<groupId>org.slf4j</groupId>-->
<!--<artifactId>slf4j-log4j12</artifactId>-->
<!--<version>1.6.3</version>-->
<!--<scope>compile</scope>-->
<!--</dependency>-->
<!-- ============================================== -->
<!-- ============================================== -->
<!-- WEB JARS [BOOTSTRAP CSS, JQUERY] -->
<!-- ============================================== -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.4</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery-ui</artifactId>
<version>1.10.3</version>
</dependency>
<!-- ============================================== -->
<!--Quartz is a batch scheduler-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
<!-- ============================================== -->
<!-- SWAGGER API DOCUMENTATION -->
<!-- ============================================== -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.4.0</version>
</dependency>
<!-- ============================================== -->
<!-- CRM INTEGRATION-->
<!-- ============================================== -->
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>adal4j</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>oauth2-oidc-sdk</artifactId>
<version>4.5</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>com.astontech.global.notification</groupId>
<artifactId>global.notification</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>com.astontech.global.integration.crm</groupId>
<artifactId>global.integration.crm</artifactId>
<version>2.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release</url>
</repository>
<repository>
<id>org.jboss.repository.releases</id>
<name>JBoss Maven Release Repository</name>
<url>https://repository.jboss.org/nexus/content/repositories/releases</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
<distributionManagement>
<repository>
<id>central</id>
<name>artifactory.astontech.com-releases</name>
<url>http://artifactory.astontech.com:8081/artifactory/libs-release-local</url>
</repository>
</distributionManagement>
Application.java
package mvc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class Application extends SpringBootServletInitializer
{
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args)
{
SpringApplication.run(Application.class, args);
}
}
CustomSuccessHandler.java
package mvc.configuration;
import mvc.common.LogHelper;
import mvc.domain.Engineer;
import mvc.services.EngineerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@Component
public class CustomSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
@Autowired
EngineerService engineerService;
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@Override
protected void handle(HttpServletRequest request, HttpServletResponse response,
Authentication authentication)
throws IOException {
HttpSession session = request.getSession();
System.out.println("CustomSuccessHandler - handle()");
String targetUrl = determineTargetUrl(authentication, session);
if (response.isCommitted()) {
System.out.println("Can't redirect");
return;
}
redirectStrategy.sendRedirect(request, response, targetUrl);
}
/*
This method extracts the roles of the currently logged-in user and returns
appropriate URL according to their role
ROLES: Timecard Admin
Timecard Billing
Timecard Engineer
Timecard Superuser
*/
protected String determineTargetUrl(Authentication authentication, HttpSession session) throws IOException{
String url = "";
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
List<String> roles = new ArrayList<String>();
for (GrantedAuthority grantedAuthority : authorities) {
roles.add(grantedAuthority.getAuthority());
}
LogHelper.viewMaster(true, false, "USER ROLES", roles);
if (isTimecardAdmin(roles)) {
LogHelper.viewMaster(true, "User has role: PAYROLL", "i");
session.setAttribute("userRole", "PAYROLL");
session.setAttribute("username", authentication.getName());
url = "/payroll";
}
else if (isTimecardBilling(roles)) {
LogHelper.viewMaster(true, "User has role: BILLING", "i");
url = "/billing";
}
else if (isTimecardEngineer(roles)) {
// ADD GENERAL ROLE OF "ENGINEER"
LogHelper.viewMaster(true, "User has role: ENGINEER", "i");
session.setAttribute("userRole", "ENGINEER");
// RETRIEVE ENGINEER DETAILS FROM DB & CRM
setCrmEngineer(session, authentication);
// REDIRECT
url = "/engineer";
}
else if (isTimecardSuperuser(roles)) {
LogHelper.viewMaster(true, "User has role: SUPER USER", "i");
session.setAttribute("userRole", "SUPER_USER");
url = "/super_user";
}
else {
url = "/accessDenied"; //todo: create an "/accessDenied" controller/view
}
return url;
}
private boolean isTimecardAdmin(List<String> roles) {
return (roles.contains("Timecard Admin") ||
roles.contains("ROLE_Timecard Admin") ||
roles.contains("ROLE_PAYROLL"));
}
private boolean isTimecardBilling(List<String> roles) {
return (roles.contains("Timecard Billing"));
}
private boolean isTimecardEngineer(List<String> roles) {
return (roles.contains("Field Engineer - Cisco") ||
roles.contains("Field Engineer - Dev") ||
roles.contains("ROLE_Field Engineer - Dev"));
}
private boolean isTimecardSuperuser(List<String> roles) {
return (roles.contains("Timecard Superuser") || roles.contains("ROLE_SUPER_USER"));
}
private void setCrmEngineer(HttpSession session, Authentication authentication) throws IOException{
//GET USERNAME BASED ON SPRING SECURITY METHOD
String username = authentication.getName();
LogHelper.viewMaster(true, true, "CRM ENGINEER:", username);
//SET USERNAME IN SESSION
session.setAttribute("username", username);
// CALL ENGINEER SERVICE TO RETRIEVE ENGINEER
Engineer loggedInEngineer = engineerService.getLoggedInEngineer(username);
// SET THAT INTO SESSION "loggedInEngineer"
session.setAttribute("loggedInEngineer", loggedInEngineer);
}
}
the EngineerService & Concrete Implementation are a bit extensive, and i can post them if they are requested.
EngineerRepository.java
package mvc.repositories;
import mvc.domain.Engineer;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
public interface EngineerRepository extends CrudRepository<Engineer, Integer> {
@Query("SELECT a from Engineer a where a.username = ?1")
Engineer findByUsername(String username);
@Query("SELECT COUNT(u) FROM Timecard u WHERE u.engineer.id=?1 AND u.isOnTime =false ")
int findTimeCardLateCount(Integer engineerId);
@Query("select a from Engineer a where a.isTrainee = ?1")
Iterable<Engineer> findByIsTrainee(boolean isTrainee);
}
Engineer.java
package mvc.domain;
import javax.persistence.*;
@Entity
public class Engineer {
//region PROPERTIES
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Version
private Integer version;
Boolean isOverTimeEligible = false;
Boolean isPtoEligible = false;
Boolean isTrainee = false;
private String adpId;
private String technology;
private String username;
@OneToOne (cascade = CascadeType.ALL, fetch = FetchType.EAGER)
CrmEngineer crmEngineer;
//region CONSTRUCTORS
public Engineer() {}
public Engineer(CrmEngineer crmEngineer) {
this.crmEngineer = crmEngineer;
this.username = crmEngineer.getAston_astonemailaddress().split("@")[0];
}
//endregion
public Engineer(String username) {
this.username = username;
}
public String getAdpId() {
return adpId;
}
public void setAdpId(String adpId) {
this.adpId = adpId;
}
public String getTechnology() {
return technology;
}
public void setTechnology(String technology) {
this.technology = technology;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
public Boolean getIsOverTimeEligible() {
return isOverTimeEligible;
}
public void setIsOverTimeEligible(Boolean isOverTimeEligible) {
this.isOverTimeEligible = isOverTimeEligible;
}
public Boolean getIsPtoEligible() {
return isPtoEligible;
}
public void setIsPtoEligible(Boolean isPtoEligible) {
this.isPtoEligible = isPtoEligible;
}
public CrmEngineer getCrmEngineer() {
return crmEngineer;
}
public void setCrmEngineer(CrmEngineer crmEngineer) {
this.crmEngineer = crmEngineer;
}
public Boolean getIsTrainee() {
return isTrainee;
}
public void setIsTrainee(Boolean isTrainee) {
this.isTrainee = isTrainee;
}
}
Upvotes: 1
Views: 427
Reputation: 175
I am able to reproduce this consistently using:
$ eb deploy
But i can get the same war file to load without issue if i goto the gui web console and redeploy the same war from Application Versions.
I am going to guess that this is some sort of error with the Elastic Beanstalk Agent when the war is deployed up via the python eb cli tools.
Elastic Beanstalk version:
64bit Amazon Linux 2017.03 v2.6.1 running Tomcat 8 Java 8
eb cli version:
EB CLI 3.10.1 (Python 3.6.0)
I'll keep jiggling the handle via the web gui when I deploy, and consider this resolved. However if anyone else has run across this and has a better workaround I'd love to hear it.
-cheers
Upvotes: 1