0

我最终希望创建一个支持 EJB 3+、传统 HTTP 请求以及最终 JPA/Hibernate 的 RESTful API。我正在使用 Eclipse 版本 2021-03,运行 JBOSS Wildfly 服务器,使用接口创建远程 EJB(类似于此处),最后使用 Spring boot 制作 REST API。

更新- 2021 年 4 月 22 日

根据日志输出,远程 EJB 被创建并且 RESTful 路由在 Web 服务器上工作。客户端 pom.xml 中有 EJB 依赖项的条目,我能够注入 EJB 依赖项,但是在查找过程中出现命名异常。我已多次检查 JNDI 绑定信息,但仍然出现异常。任何帮助将不胜感激。


EJB 远程代码

HelloStatefulWorld.java

@Remote
public interface HelloStatefulWorld {

    int howManyTimes();
    String getHelloWorld();
}

HelloStatefulWorldEJB.java

@Stateful(name="HelloStatefulWorld")
public class HelloStatefulWorldEJB implements HelloStatefulWorld {

    private int howManyTimes = 0;

    public int howManyTimes() {
        return howManyTimes;
    }

    public String getHelloWorld() {
        howManyTimes++;
        return "Hello Stateful World!";
    }
}

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>swe642a4-ejb-remote</groupId>
    <artifactId>swe642a4-ejb-remote</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>ejb</packaging>
    <name>swe642a4-ejb-remote</name>
    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>8.0.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <sourceDirectory>ejbModule</sourceDirectory>
        <resources>
            <resource>
                <directory>ejbModule</directory>
                <excludes>
                    <exclude>**/*.java</exclude>
                </excludes>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-ejb-plugin</artifactId>
                <version>3.0.1</version>
                <configuration>
                    <ejbVersion>3.2</ejbVersion>
                    <generateClient>true</generateClient>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

EJB 客户端代码/REST API

ServletInitializer.java

public class ServletInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Swe642a4EjbClientApplication.class);
    }

}

Swe642a4EjbClientApplication.java

import com.mastertheboss.springboot.HelloStatefulWorld;

@SpringBootApplication
public class Swe642a4EjbClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(Swe642a4EjbClientApplication.class, args);
    }
    
    @Bean   
    public Context context() throws NamingException {
        Properties jndiProps = new Properties();
        jndiProps.put("java.naming.factory.initial", "org.jboss.naming.remote.client.InitialContextFactory");
        jndiProps.put("jboss.naming.client.ejb.context", true);
        jndiProps.put("java.naming.provider.url", "http-remoting://localhost:8080");
        return new InitialContext(jndiProps);
    }
    
    @Bean
    public HelloStatefulWorld helloStatefulWorld(Context context) throws NamingException {
        return (HelloStatefulWorld) context.lookup(this.getFullName(HelloStatefulWorld.class));
    }
    
    @SuppressWarnings("rawtypes")
    private String getFullName(Class classType) {
        String moduleName = "swe642a4-ejb-remote/";
        String beanName = classType.getSimpleName();
        String viewClassName = classType.getName();
        
        return moduleName + beanName + "!" + viewClassName;
    }

}

@RestController
class SurveyController{
    
    //private HelloStatefulWorld helloStatefulWorld;
    
    /*public SurveyController(HelloStatefulWorld helloStatefulWorld) {
        this.helloStatefulWorld = helloStatefulWorld;
    }*/
    
    @RequestMapping(path="/hello/{name}", method=RequestMethod.GET)
    String hello(@PathVariable String name) {
         
             return "Hi "+name+" !";
    }
    
    /*@RequestMapping(path="/stateful", method=RequestMethod.GET)
    public String getStateful() {
        return helloStatefulWorld.getHelloWorld() + " called " + helloStatefulWorld.howManyTimes() + " times";
    }*/
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.0-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.mastertheboss.springboot</groupId>
    <artifactId>swe642a4-ejb-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>swe642a4-ejb-client</name>
    <description>EJB Client</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-classic</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>8.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.reactivestreams</groupId>
            <artifactId>reactive-streams</artifactId>
        </dependency>
        <dependency>
            <groupId>swe642a4-ejb-remote</groupId>
            <artifactId>swe642a4-ejb-remote</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <type>ejb</type>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.wildfly</groupId>
            <artifactId>wildfly-ejb-client-bom</artifactId>
            <version>23.0.1.Final</version>
            <type>pom</type>
            <exclusions>
                <exclusion>
                    <groupId>org.jboss.xnio</groupId>
                    <artifactId>xnio-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>    
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.wildfly.plugins</groupId>
                <artifactId>wildfly-maven-plugin</artifactId>
                <version>2.0.0.Final</version>
            </plugin>           
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>            
        </repository>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>            
        </pluginRepository>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>

Eclipse 日志输出

11:54:24,272 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-3) WFLYEJB0473: JNDI bindings for session bean named 'HelloStatefulWorld' in deployment unit 'deployment "swe642a4-ejb-remote.jar"' are as follows:

    java:global/swe642a4-ejb-remote/HelloStatefulWorld!com.mastertheboss.springboot.HelloStatefulWorld
    java:app/swe642a4-ejb-remote/HelloStatefulWorld!com.mastertheboss.springboot.HelloStatefulWorld
    java:module/HelloStatefulWorld!com.mastertheboss.springboot.HelloStatefulWorld
    java:jboss/exported/swe642a4-ejb-remote/HelloStatefulWorld!com.mastertheboss.springboot.HelloStatefulWorld
    ejb:/swe642a4-ejb-remote/HelloStatefulWorld!com.mastertheboss.springboot.HelloStatefulWorld?stateful
    java:global/swe642a4-ejb-remote/HelloStatefulWorld
    java:app/swe642a4-ejb-remote/HelloStatefulWorld
    java:module/HelloStatefulWorld

11:54:24,597 INFO  [org.jboss.weld.Version] (MSC service thread 1-5) WELD-000900: 3.1.6 (Final)
11:54:24,878 INFO  [org.infinispan.CONTAINER] (ServerService Thread Pool -- 78) ISPN000128: Infinispan version: Infinispan 'Corona Extra' 11.0.9.Final
11:54:24,922 INFO  [org.infinispan.CONFIG] (MSC service thread 1-5) ISPN000152: Passivation configured without an eviction policy being selected. Only manually evicted entities will be passivated.
11:54:24,924 INFO  [org.infinispan.CONFIG] (MSC service thread 1-5) ISPN000152: Passivation configured without an eviction policy being selected. Only manually evicted entities will be passivated.
11:54:24,999 INFO  [org.infinispan.PERSISTENCE] (ServerService Thread Pool -- 78) ISPN000556: Starting user marshaller 'org.wildfly.clustering.infinispan.spi.marshalling.InfinispanProtoStreamMarshaller'
11:54:25,194 WARN  [org.jboss.as.ee] (MSC service thread 1-8) WFLYEE0007: Not installing optional component org.springframework.http.server.reactive.ServletServerHttpResponse$ResponseAsyncListener due to an exception (enable DEBUG log level to see the cause)
11:54:25,196 WARN  [org.jboss.as.ee] (MSC service thread 1-8) WFLYEE0007: Not installing optional component org.springframework.http.server.ServletServerHttpAsyncRequestControl due to an exception (enable DEBUG log level to see the cause)
11:54:25,199 WARN  [org.jboss.as.ee] (MSC service thread 1-8) WFLYEE0007: Not installing optional component org.springframework.web.context.request.async.StandardServletAsyncWebRequest due to an exception (enable DEBUG log level to see the cause)
11:54:25,199 WARN  [org.jboss.as.ee] (MSC service thread 1-8) WFLYEE0007: Not installing optional component org.springframework.http.server.reactive.ServletHttpHandlerAdapter$HttpHandlerAsyncListener due to an exception (enable DEBUG log level to see the cause)
11:54:25,201 WARN  [org.jboss.as.ee] (MSC service thread 1-8) WFLYEE0007: Not installing optional component org.springframework.http.server.reactive.ServletServerHttpRequest$RequestAsyncListener due to an exception (enable DEBUG log level to see the cause)
11:54:25,210 INFO  [org.jboss.as.clustering.infinispan] (ServerService Thread Pool -- 78) WFLYCLINF0002: Started http-remoting-connector cache from ejb container
11:54:25,390 INFO  [io.undertow.servlet] (ServerService Thread Pool -- 91) 3 Spring WebApplicationInitializers detected on classpath
Handler java.util.logging.ConsoleHandler is not defined
Handler java.util.logging.ConsoleHandler is not defined
Handler java.util.logging.ConsoleHandler is not defined
11:54:27,535 ERROR [org.springframework.boot.SpringApplication] (ServerService Thread Pool -- 83) Application run failed: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloStatefulWorld' defined in com.mastertheboss.springboot.swe642a4ejbclient.Swe642a4EjbClientApplication: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mastertheboss.springboot.HelloStatefulWorld]: Factory method 'helloStatefulWorld' threw exception; nested exception is javax.naming.NamingException: WFLYNAM0062: Failed to lookup swe642a4-ejb-remote/HelloStatefulWorld!com.mastertheboss.springboot.HelloStatefulWorld [Root exception is java.lang.RuntimeException: org.jboss.as.ejb3.component.EJBComponentUnavailableException: WFLYEJB0467: The request was rejected as the container is suspended]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:769)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:337)
    at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:175)
    at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:155)
    at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:97)
    at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:174)
    at io.undertow.servlet.core.DeploymentManagerImpl$1.call(DeploymentManagerImpl.java:204)
    at io.undertow.servlet.core.DeploymentManagerImpl$1.call(DeploymentManagerImpl.java:187)
    at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:42)
    at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
    at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
    at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:255)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:96)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:78)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
    at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
    at java.lang.Thread.run(Unknown Source)
    at org.jboss.threads.JBossThread.run(JBossThread.java:513)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mastertheboss.springboot.HelloStatefulWorld]: Factory method 'helloStatefulWorld' threw exception; nested exception is javax.naming.NamingException: WFLYNAM0062: Failed to lookup swe642a4-ejb-remote/HelloStatefulWorld!com.mastertheboss.springboot.HelloStatefulWorld [Root exception is java.lang.RuntimeException: org.jboss.as.ejb3.component.EJBComponentUnavailableException: WFLYEJB0467: The request was rejected as the container is suspended]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
    ... 40 more
Caused by: javax.naming.NamingException: WFLYNAM0062: Failed to lookup swe642a4-ejb-remote/HelloStatefulWorld!com.mastertheboss.springboot.HelloStatefulWorld [Root exception is java.lang.RuntimeException: org.jboss.as.ejb3.component.EJBComponentUnavailableException: WFLYEJB0467: The request was rejected as the container is suspended]
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:159)
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:83)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:207)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:193)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:189)
    at org.wildfly.naming.client.remote.RemoteServerTransport.handleLookup(RemoteServerTransport.java:203)
    at org.wildfly.naming.client.remote.RemoteServerTransport$1.handleMessage(RemoteServerTransport.java:123)
    at org.jboss.remoting3.remote.RemoteConnectionChannel.lambda$handleMessageData$3(RemoteConnectionChannel.java:430)
    at org.jboss.remoting3.EndpointImpl$TrackingExecutor.lambda$execute$0(EndpointImpl.java:991)
    at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
    at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
    at org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1280)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.RuntimeException: org.jboss.as.ejb3.component.EJBComponentUnavailableException: WFLYEJB0467: The request was rejected as the container is suspended
    at org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor$2$1.getReference(EjbJndiBindingsDeploymentUnitProcessor.java:273)
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:143)
    ... 14 more
Caused by: org.jboss.as.ejb3.component.EJBComponentUnavailableException: WFLYEJB0467: The request was rejected as the container is suspended
    at org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor$2$1.getReference(EjbJndiBindingsDeploymentUnitProcessor.java:265)
    ... 15 more
4

0 回答 0