服务器 Tomcat v8.0 位于本地主机的服务器无法启动 - JSF、CDI、JAVA、TOMCAT、ECLIPSE

Server Tomcat v8.0 Server at localhost failed to start - JSF, CDI, JAVA, TOMCAT, ECLIPSE

下午好,我遇到了 Tomcat 和 CDI 的集成问题。我在 Whosebug 和许多其他网站上阅读了很多帖子。

这是我的bean:

package org.servidor.beans;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;
import org.servidor.modelo.Jugador;

@Named
@SessionScoped
public class JugadoresController implements Serializable {

    /* Identificador serial UID de la clase serializable */
    private static final long serialVersionUID = 1L;

    /* Lista de jugadores conectados */
    public List<Jugador> lista = new ArrayList<>();

    public List<Jugador> getLista() {
        return lista;
    }

    public void setLista(List<Jugador> lista) {
        this.lista = lista;
    }

    /* Metodos de uso en la vista */
    public int getNumeroJugadores() {
        return this.lista.size();
    }

    public void eliminarTodosJugadores() {
        lista.clear();
    }

    public void eliminarJugador(Jugador jug) {
        Jugador jug_eliminar = null;
        for (Jugador juga : lista) {
            if (juga.getNick().equals(jug.getNick())) {
                jug_eliminar = juga;
            }
        }
        lista.remove(jug_eliminar);
    }

    public void jugadorEditado(Jugador jug) {
        editaJugador(jug);
    }

    public void modificarCancelado() {
        recargaPagina();

    }

    public void editaJugador(Jugador jugador) {
        for (Jugador jug : lista) {
            if (jug.getNick().equals(jugador.getNick())) {
                jug.setGrupo(jugador.getGrupo());
                jug.setPartida(jugador.getPartida());
            }
        }
    }

    public void recargaPagina() {
        try {
            ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
            ec.redirect(((HttpServletRequest) ec.getRequest()).getRequestURI());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void simularAccesoJugador() {
        // Creamos un jugador de forma aleatoria
        Jugador jugador = new Jugador();

        // Datos
        int grupo = (int) Math.floor(Math.random() * (10 - (1 + 1)) + (1));
        int partida = (int) Math.floor(Math.random() * (20 - (11 + 1)) + (11));
        int nick = (int) Math.floor(Math.random() * (50 - (1 + 1)) + (1));
        jugador.setGrupo(grupo);
        jugador.setPartida(partida);
        jugador.setNick("Alberto_" + nick);

        lista.add(jugador);

    }

}

这是我的配置:

Pom.xml 依赖关系:

<dependencies>
    <!-- Dependencias para implementar JSF 2.2 -->
    <dependency>
        <groupId>com.sun.faces</groupId>
        <artifactId>jsf-api</artifactId>
        <version>2.2.0</version>
    </dependency>
    <dependency>
        <groupId>com.sun.faces</groupId>
        <artifactId>jsf-impl</artifactId>
        <version>2.2.16</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-catalina</artifactId>
        <version>8.0.32</version>
    </dependency>
    <!-- Dependencias para implementar PrimeFaces 6.2 -->
    <dependency>
        <groupId>org.primefaces</groupId>
        <artifactId>primefaces</artifactId>
        <version>6.2</version>
    </dependency>
    <!-- For CDI -->
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <version>7.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.enterprise</groupId>
        <artifactId>cdi-api</artifactId>
        <version>2.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.jboss.weld.servlet</groupId>
        <artifactId>weld-servlet-shaded</artifactId>
        <version>3.0.3.Final</version>
    </dependency>
</dependencies>

Context.xml 位于 META-INF/:

<Context>
<Resource name="BeanManager" 
    auth="Container"
    type="javax.enterprise.inject.spi.BeanManager"
    factory="org.jboss.weld.resources.ManagerObjectFactory" />
</Context>

Web.xml 在 WEB-INF/:

<welcome-file-list>
    <welcome-file>index.xhtml</welcome-file>
</welcome-file-list>

<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
</servlet-mapping>

<resource-env-ref>
    <!-- Enable Weld CDI, also needs META-INF/context.xml entry -->
    <resource-env-ref-name>BeanManager</resource-env-ref-name>
    <resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>
</resource-env-ref>

beans.xml 在 WEB-INF/:

<?xml version="1.0" encoding="UTF-8"?>
<beans
  xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
  http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
  bean-discovery-mode="annotated">
</beans>

Tomcat版本:

Server version: Apache Tomcat/8.0.32 (Ubuntu)

Tomcat 工作正常,但是如果我将依赖项添加到我的 pom.xml:

<dependency>
    <groupId>org.jboss.weld.servlet</groupId>
    <artifactId>weld-servlet-shaded</artifactId>
    <version>3.0.3.Final</version>
</dependency>

<dependency>
   <groupId>org.jboss.weld.servlet</groupId>
   <artifactId>weld-servlet</artifactId>
   <version>2.4.4.Final</version>
</dependency>

当我 运行 我的应用程序出现以下错误时:

Server Tomcat v8.0 Server at localhost failed to start.

如果我显示控制台日志:

INFO: WELD-ENV-001008: Initialize Weld using ServletContainerInitializer
ago 10, 2018 7:53:01 PM org.jboss.weld.bootstrap.WeldStartup <clinit>
INFO: WELD-000900: 3.0.3 (Final)
ago 10, 2018 7:53:01 PM org.jboss.weld.environment.deployment.discovery.ReflectionDiscoveryStrategy processAnnotatedDiscovery
INFO: WELD-ENV-000014: Falling back to Java Reflection for bean-discovery-mode="annotated" discovery. Add org.jboss:jandex to the classpath to speed-up startup.
ago 10, 2018 7:53:01 PM org.jboss.weld.bootstrap.WeldStartup startContainer
INFO: WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
ago 10, 2018 7:53:01 PM org.jboss.weld.bootstrap.events.BeforeBeanDiscoveryImpl addAnnotatedType
WARN: WELD-000146: BeforeBeanDiscovery.addAnnotatedType(AnnotatedType<?>) used for class com.sun.faces.flow.FlowDiscoveryCDIHelper is deprecated from CDI 1.1!
ago 10, 2018 7:53:01 PM org.jboss.weld.environment.tomcat.TomcatContainer initialize
INFO: WELD-ENV-001100: Tomcat 7+ detected, CDI injection will be available in Servlets, Filters and Listeners.
ago 10, 2018 7:53:01 PM org.apache.catalina.core.ContainerBase startInternal

也许,这里是关键:

GRAVE: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/servidor-websocket]]
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:192)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:916)
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:871)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/servidor-websocket]]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:153)
    ... 6 more
Caused by: org.jboss.weld.exceptions.DefinitionException: WELD-000075: Normal scoped managed bean implementation class has a public field:  [EnhancedAnnotatedFieldImpl] public org.servidor.beans.JugadoresController.lista
    at org.jboss.weld.bean.ManagedBean.checkBeanImplementation(ManagedBean.java:231)
    at org.jboss.weld.bean.AbstractClassBean.internalInitialize(AbstractClassBean.java:74)
    at org.jboss.weld.bean.ManagedBean.internalInitialize(ManagedBean.java:105)
    at org.jboss.weld.bean.RIBean.initialize(RIBean.java:69)
    at org.jboss.weld.bootstrap.ConcurrentBeanDeployer.doWork(ConcurrentBeanDeployer.java:96)
    at org.jboss.weld.bootstrap.ConcurrentBeanDeployer.doWork(ConcurrentBeanDeployer.java:93)
    at org.jboss.weld.executor.IterativeWorkerTaskFactory.call(IterativeWorkerTaskFactory.java:62)
    at org.jboss.weld.executor.IterativeWorkerTaskFactory.call(IterativeWorkerTaskFactory.java:55)
    ... 4 more

但是如果我删除 weld-servlet 依赖项,显然 CDI 不起作用。

我真的很绝望,我不知道为什么会这样。

请帮忙。太感谢了。

* 已解决 *

问题是 JugadoresController.java 中我的变量 'lista' 的类型,它必须是 private

此外,项目中的所有 类 都必须实现 Serializable。

非常感谢@Kukeltje 和@ACV 更正我的报告,最重要的是感谢@bdkosher 给我解决方案。

堆栈跟踪显示问题

Caused by: org.jboss.weld.exceptions.DefinitionException: WELD-000075: Normal scoped managed bean implementation class has a public field:  [EnhancedAnnotatedFieldImpl] public org.servidor.beans.JugadoresController.lista
at org.jboss.weld.bean.ManagedBean.checkBeanImplementation(ManagedBean.java:231)

您需要将 JugadoresController 更改为

private List<Jugador> lista;

虽然,主要问题仍然存在,我阅读了其他post关于问题的内容,但没有办法。

我试图在 JSF Bean 中实现 WebSocket ServerEndPoint,但是当我使用 CDI 将 bean 注入我的服务器时,我得到 NullPointerException。

这是我的ServerEndPoint:

package org.servidor.beans;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint("/websocket")
@SessionScoped
public class WebsocketController implements Serializable {

    private static final long serialVersionUID = 1L;

    static final List<Session> conexiones = new ArrayList<>();

    @Inject
    private JugadoresController jugadorController;

    @OnOpen
    public void iniciaSesion(Session session) {
        conexiones.add(session);
        jugadorController.getNumeroJugadores();
    }

    @OnMessage
    public void onMessage(String mensaje, Session sesion) {
        System.out.println("Mensaje recibido: " + mensaje);
    }

    @OnClose
    public void finConexion(Session session) {
        try {
            session.close(); // se cierra la conexión
            conexiones.remove(session); // se retira de la lista
        } catch (IOException ex) {
        }
        System.out.println("Conexion cerrada.");
    }

}

这是我的豆子:

package org.servidor.beans;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;
import org.servidor.modelo.Jugador;

@Named
@SessionScoped
public class JugadoresController implements Serializable {

    /* Identificador serial UID de la clase serializable */
    private static final long serialVersionUID = 1L;

    /* Lista de jugadores conectados */
    private List<Jugador> lista = new ArrayList<>();

    public List<Jugador> getLista() {
        return lista;
    }

    public void setLista(List<Jugador> lista) {
        this.lista = lista;
    }

    /* Metodos de uso en la vista */
    public int getNumeroJugadores() {
        return this.lista.size();
    }

    public void eliminarTodosJugadores() {
        lista.clear();
    }

    public void eliminarJugador(Jugador jug) {
        Jugador jug_eliminar = null;
        for (Jugador juga : lista) {
            if (juga.getNick().equals(jug.getNick())) {
                jug_eliminar = juga;
            }
        }
        lista.remove(jug_eliminar);
    }

    public void jugadorEditado(Jugador jug) {
        editaJugador(jug);
    }

    public void modificarCancelado() {
        recargaPagina();

    }

    public void editaJugador(Jugador jugador) {
        for (Jugador jug : lista) {
            if (jug.getNick().equals(jugador.getNick())) {
                jug.setGrupo(jugador.getGrupo());
                jug.setPartida(jugador.getPartida());
            }
        }
    }

    public void recargaPagina() {
        try {
            ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
            ec.redirect(((HttpServletRequest) ec.getRequest()).getRequestURI());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void simularAccesoJugador() {
        // Creamos un jugador de forma aleatoria
        Jugador jugador = new Jugador();

        // Datos
        int grupo = (int) Math.floor(Math.random() * (10 - (1 + 1)) + (1));
        int partida = (int) Math.floor(Math.random() * (20 - (11 + 1)) + (11));
        int nick = (int) Math.floor(Math.random() * (50 - (1 + 1)) + (1));
        jugador.setGrupo(grupo);
        jugador.setPartida(partida);
        jugador.setNick("Alberto_" + nick);

        lista.add(jugador);

    }

}

这是痕迹:

GRAVE: No error handling configured for [org.servidor.beans.WebsocketController] and the following error occurred
java.lang.NullPointerException
    at org.servidor.beans.WebsocketController.iniciaSesion(WebsocketController.java:29)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.tomcat.websocket.pojo.PojoEndpointBase.doOnOpen(PojoEndpointBase.java:66)
    at org.apache.tomcat.websocket.pojo.PojoEndpointServer.onOpen(PojoEndpointServer.java:70)
    at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.init(WsHttpUpgradeHandler.java:128)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:705)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)

ago 10, 2018 9:36:25 PM org.apache.tomcat.websocket.pojo.PojoEndpointBase onError

¿有什么建议吗?我将不胜感激。