org.apache.catalina.core.StandardContext.startInternal一个或多个侦听器无法启动

Are*_*efe 6 java rest spring cxf maven

我在使用Java/Spring/ Apache Cxf网络应用程序,突然间,我做了一些显然很幼稚的更改,却收到了错误消息,

25-Aug-2017 11:48:43.036 INFO [RMI TCP Connection(2)-127.0.0.1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
log4j:WARN No appenders could be found for logger (org.apache.cxf.common.logging.LogUtils).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
25-Aug-2017 11:48:43.540 SEVERE [RMI TCP Connection(2)-127.0.0.1] org.apache.catalina.core.StandardContext.startInternal One or more listeners failed to start. Full details will be found in the appropriate container log file
25-Aug-2017 11:48:43.554 SEVERE [RMI TCP Connection(2)-127.0.0.1] org.apache.catalina.core.StandardContext.startInternal Context [] startup failed due to previous errors
[2017-08-25 11:48:43,586] Artifact jaxrs-tutorials:war exploded: Error during artifact deployment. See server log for details.
25-Aug-2017 11:48:49.258 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/Applications/Tomcat-8.5.16/webapps/manager]
25-Aug-2017 11:48:49.310 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/Applications/Tomcat-8.5.16/webapps/manager] has finished in [51] ms
Run Code Online (Sandbox Code Playgroud)

我想这是info错误的主要原因,

25-Aug-2017 11:48:43.540 SEVERE [RMI TCP Connection(2)-127.0.0.1] org.apache.catalina.core.StandardContext.startInternal One or more listeners failed to start. Full details will be found in the appropriate container log file
25-Aug-2017 11:48:43.554 SEVERE [RMI TCP Connection(2)-127.0.0.1] org.apache.catalina.core.StandardContext.startInternal Context [] startup failed due to previous errors
Run Code Online (Sandbox Code Playgroud)

提供了项目结构,

在此处输入图片说明

config目录用于Java annotation based config和,下面提供了代码。

AppConfig文件,

@Configuration
@ComponentScan(AppConfig.SERVICE_PACKAGE)
public class AppConfig {

    public static final String BASE_PACKAGE = "mobi.puut";
    public static final String SERVICE_PACKAGE = BASE_PACKAGE + ".services";
    private static final String RESOURCES_PACKAGE = BASE_PACKAGE + ".rest";
    private static final String PROVIDER_PACKAGE = BASE_PACKAGE + ".rest.provider";

    public static final String API_BASE = "/api/*";

    @ApplicationPath("/")
    public class JaxRsApiApplication extends Application {
    }

    @Bean(destroyMethod = "shutdown")
    public SpringBus cxf() {
        return new SpringBus();
    }

    @Bean
    @DependsOn("cxf")
    public Server jaxRsServer(ApplicationContext appContext) {
        JAXRSServerFactoryBean factory = RuntimeDelegate.getInstance().createEndpoint(jaxRsApiApplication(), JAXRSServerFactoryBean.class);
        factory.setServiceBeans(restServiceList(appContext));
        factory.setAddress("/" + factory.getAddress());
        factory.setProviders(restProviderList(appContext, jsonProvider()));
        return factory.create();
    }

    @Bean
    public JaxRsApiApplication jaxRsApiApplication() {
        return new JaxRsApiApplication();
    }

    @Bean
    public JacksonJsonProvider jsonProvider() {
        return new JacksonJsonProvider();
    }

    private List<Object> restServiceList(ApplicationContext appContext) {
        return RestServiceBeanScanner.scan(appContext, AppConfig.RESOURCES_PACKAGE);
    }

    private List<Object> restProviderList(final ApplicationContext appContext,
                                          final JacksonJsonProvider jsonProvider) {
        final List<Object> providers = RestProviderBeanScanner.scan(appContext, PROVIDER_PACKAGE);
        providers.add(jsonProvider);
        return providers;
    }

}
Run Code Online (Sandbox Code Playgroud)

WebInitializer提供,

public class WebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        servletContext.addListener(new ContextLoaderListener(createWebAppContext()));
        addApacheCxfServlet(servletContext);
    }

    private void addApacheCxfServlet(ServletContext servletContext) {
        CXFServlet cxfServlet = new CXFServlet();

        ServletRegistration.Dynamic appServlet = servletContext.addServlet("CXFServlet", cxfServlet);
        appServlet.setLoadOnStartup(1);

        Set<String> mappingConflicts = appServlet.addMapping(AppConfig.API_BASE);
    }

    private WebApplicationContext createWebAppContext() {
        AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
        appContext.register(AppConfig.class);
        return appContext;
    }

}
Run Code Online (Sandbox Code Playgroud)

我已经看到了与平台类似的问题,但这些问题并没有帮助我,而且我掌握的信息很少,无法解决问题。

如何使用logger以获得更多信息以及应该在哪里使用它们?此外,有关解决问题的任何见解也将有所帮助。我已经JAR使用mvn clean installmvn idea:idea命令更新了文件。

UPDATE

Tomcat Localhost Log

在此处输入图片说明

Tomcat Catalina Log

在此处输入图片说明

Are*_*efe 6

我想就此问题以及为解决该问题而采取的步骤写一个详细的答案。

答:没有足够的日志记录信息。我查了一下POM,发现了这个,

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
            <exclusions>
                <!-- Exclude Commons Logging in favor of SLF4j -->
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
Run Code Online (Sandbox Code Playgroud)

我已经排除了日志记录的支持,SLF4J而我只是删除了排除XML标记以获得更多的日志记录信息。所以变成这样

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
Run Code Online (Sandbox Code Playgroud)

B.现在,我得到了日志记录信息。我有这样的错误信息,

Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'userService' for bean class [mobi.puut.services.UserServiceImpl] conflicts with existing, non-compatible bean definition of same name and class [mobi.puut.services.UserService2Impl]
Run Code Online (Sandbox Code Playgroud)

您将获得ConflictingBeanDefinitionException用于创建具有相同名称的Bean的。尽管我有一些使用的经验,但Spring我需要使用创建一个项目,Apache Cxf因此出于这个目的克隆了一个演示项目。他们有一个相同的实体User,相同definition - interface又相同implementation。尽管我需要refactored该项目中的所有类,而且似乎没有明显的错误,但仍然存在一个问题-我"userService在接口的2种实现中都保留了相同的bean名称。

User2实体中的类,

public class User2 {

    private Integer id;
    private String name;

    public User2() {
    }

    public User2(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return String.format("{id=%s,name=%s}", id, name);
    }
}
Run Code Online (Sandbox Code Playgroud)

User实体中的类,

@Entity
@Table(name = "users")
public class User {

    @Id
    @Column
    @NotNull
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @NotNull
    @Column(name = "name")
    @Size(min = 5, max = 45, message = "Name must be between 5 and 45 characters.")
    private String name;

    public User() {

    }

    public User(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }

    public User(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof User)) return false;

        User user = (User) o;

        if (getId() != user.getId()) return false;
        return getName().equals(user.getName());
    }

    @Override
    public int hashCode() {
        int result = getId();
        result = 31 * result + getName().hashCode();
        return result;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
Run Code Online (Sandbox Code Playgroud)

services目录中的接口,

public interface IUserService2 {

    Collection<User2> getUsers();

    User2 getUser(Integer id);

    Response add(User2 user);
}



public interface IUserService {

    List<User> getCurrentStatuses();

    void create(User user);

    List<User> getAllUsers();
}
Run Code Online (Sandbox Code Playgroud)

目录内部接口的services实现,

@Service("userService")
public class UserService2Impl implements IUserService2 {

    private static Map<Integer, User2> users = new HashMap<Integer, User2>();

    static {
        users.put(1, new User2(1, "foo"));
        users.put(2, new User2(2, "bar"));
        users.put(3, new User2(3, "baz"));
    }

    public UserService2Impl() {
    }

    @Override
    public Collection<User2> getUsers() {
        return users.values();
    }

    @Override
    public User2 getUser(Integer id) {
        return users.get(id);
    }

    @Override
    public Response add(User2 user) {
        user.setId(users.size()+1);
        users.put(user.getId(), user);

        //do more stuff to add user to the system..
        return Response.status(Response.Status.OK).build();
    }

}


@Service("userService")
public class UserServiceImpl implements IUserService {

    @Autowired
    @Qualifier("userDao")
    public IUserDao userDao;

    public List<User> getCurrentStatuses() {
        return userDao.getAllUsers();
    }

    public void create(User user) {
        userDao.saveOrUpdate(user);
    }

    public List<User> getAllUsers() {
        List<User> users = userDao.getAllUsers();

        if (Objects.isNull(users)) {
            return null;
        }
        return users;
    }
}
Run Code Online (Sandbox Code Playgroud)

并且,有error-我注释了两个具有相同bean名称的类"userService"。我必须像这样更改它,以便为Bean提供一个不同的名称,

@Service("user2Service")
public class UserService2Impl implements IUserService2 {

    // some code
}
Run Code Online (Sandbox Code Playgroud)

而且,该错误消失了。简而言之,ConflictingBeanDefinitionException由于2个相同名称的bean而导致的错误,我只需要提供一个不同的名称。

C.我还有事情要解决。之后,当我运行程序时,我得到了

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'userDao'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'mobi.puut.database.IUserDao' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=userDao)}


// some consequent error messages not necessay to solve the issue

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'mobi.puut.database.IUserDao' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=userDao)}
Run Code Online (Sandbox Code Playgroud)

这里的错误是,UnsatisfiedDependencyException并说它不能创建名称为的bean userService。好的,这是我已集成到项目中的代码。通过字段表示的不满意依赖性为userDaouserDao是的接口的实例IUserDao,它是@autowired这样的,

    @Autowired
    public IUserDao userDao;
Run Code Online (Sandbox Code Playgroud)

这是代码的更多见解,

@Service("userService")
public class UserServiceImpl implements IUserService {

    @Autowired
    public IUserDao userDao;


     public List<User> getCurrentStatuses() {
        return userDao.getAllUsers();
    }

    public void create(User user) {
        userDao.saveOrUpdate(user);
    }

    public List<User> getAllUsers() {
        List<User> users = userDao.getAllUsers();

        if (Objects.isNull(users)) {
            return null;
        }
        return users;
    }
}
Run Code Online (Sandbox Code Playgroud)

我在database目录中有一个接口,并因此为用户实现了该接口。接口名称为IUserDao和看起来

soemthing like this, 


public interface IUserDao {

    boolean create(User user);

    void saveOrUpdate(User user);

    boolean create(List<User> users);

    List<User> getAllUsers();

    User getById(int id);
}
Run Code Online (Sandbox Code Playgroud)

并且,

@Repository("userDao")
public class UserDaoImpl implements IUserDao {

    @Autowired
    private SessionFactory sessionFactory;

    // the HQL queries

}
Run Code Online (Sandbox Code Playgroud)

错误消息的后续部分是NoSuchBeanDefinitionException,应用未找到类型(类)的合格Bean IUserDao。我HQL在实现的过程中拥有所有查询,IUserDao并且代码之前运行良好。

我必须花一点时间思考,最后,我有一个直觉,可能是该database层已NOT集成到应用程序中。这是configuration我用过的

public class WebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        servletContext.addListener(new ContextLoaderListener(createWebAppContext()));
        addApacheCxfServlet(servletContext);
    }

    private void addApacheCxfServlet(ServletContext servletContext) {
        CXFServlet cxfServlet = new CXFServlet();

        ServletRegistration.Dynamic appServlet = servletContext.addServlet("CXFServlet", cxfServlet);
        appServlet.setLoadOnStartup(1);

        Set<String> mappingConflicts = appServlet.addMapping(AppConfig.API_BASE);
    }

    private WebApplicationContext createWebAppContext() {
        AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();

        // register all the config classes here
        appContext.register(AppConfig.class);
        return appContext;
    }

}
Run Code Online (Sandbox Code Playgroud)

显然,no数据库代码集成在中WebInitializer。我写了一个新类,提供了database connection和的所有信息,hibernate integration看起来像这样,

@Configuration
@EnableWebMvc
@EnableTransactionManagement
@ComponentScan(basePackages = {"mobi.puut.database"})
public class DatabaseConfig {

    @Bean
    public LocalSessionFactoryBean sessionFactory() {

        //  mobi.puut.entities
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan(
                new String[]{"mobi.puut.entities"});
        sessionFactory.setHibernateProperties(hibernateProperties());

        return sessionFactory;
    }

    @Bean
    @Autowired
    public HibernateTransactionManager transactionManager(
            SessionFactory sessionFactory) {

        HibernateTransactionManager txManager
                = new HibernateTransactionManager();
        txManager.setSessionFactory(sessionFactory);

        return txManager;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }

    @Bean
    public DataSource dataSource() {

        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");

        // dataSource.setUrl("jdbc:mysql://localhost:3306/wallet?createDatabaseIfNotExist=true");
        dataSource.setUrl("jdbc:mysql://localhost:3306/Wallet");
        dataSource.setUsername("testuser");
        dataSource.setPassword("testpassword");

        return dataSource;
    }

    Properties hibernateProperties() {

        Properties properties = new Properties();
//        properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
        return properties;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,最后整合到中WebInitializer。这是我registered以前在WebInitializer

appContext.register(AppConfig.class);
Run Code Online (Sandbox Code Playgroud)

用更新了该行,

appContext.register(AppConfig.class, DatabaseConfig.class);
Run Code Online (Sandbox Code Playgroud)

最后,一切正常。因此,config目录看起来像

在此处输入图片说明

SUMMERY

我不得不通过3个错误解决此问题,

i. ConflictingBeanDefinitionException
ii. UnsatisfiedDependencyException
iii. NoSuchBeanDefinitionException
Run Code Online (Sandbox Code Playgroud)

ConflictingBeanDefinitionException -> 2个同名豆

UnsatisfiedDependencyException-> (= "userDao")在该类中有一个不正确使用的bean

NoSuchBeanDefinitionException->代码是正确的,但是需要在congig中添加datbase层,以便Spring IoC找到bean。

我衷心希望这对某些人有帮助。

  • 谢谢 - 关于日志记录的提示为我尝试在 Spring 应用程序中使用 bean 揭示了一个类似的问题。你今天为我打破了原木堵塞。:-D (2认同)