部署和执行EJB

时间:2017-01-23 10:24:04

标签: java java-ee ejb ejb-3.1

我是EJB的新手。这是我第一次处理EJB。

我有两个完整的应用程序。第一个应用程序是部署在WildFly 8上的EJB bean,第二个是将使用服务器上的Bean的客户端应用程序。

服务器应用程序:

package com.apress.ejb.chapter02.business;

    // Remote Interface
    @Remote
    public interface SearchFacade {
        List<String> wineSearch(String wineType);
        String wineSearchByCountry();
    }


package com.apress.ejb.chapter02.business;

    // Local Interface
    @Local
    public interface SearchFacadeLocal {
        List<String> wineSearch(String wineType);
        String wineSearchByCountry();
    }

上述接口的服务器实现:

package com.apress.ejb.chapter02;

    /**
     * Session Bean implementation class SearchFacadeBean
     */
    @Stateless(name="SearchFacade")
    //@LocalBean
    public class SearchFacadeBean implements SearchFacade, SearchFacadeLocal{

        private Map<String, String> countryMap = new HashMap<String, String>();

        /**
         * Default constructor. 
         */
        public SearchFacadeBean() {
        }

        public List<String> wineSearch(String wineType) {
            List<String> wineList = new ArrayList<String>();
            if(wineType.equals("red")){
                wineList.add("Bordeaux");
                wineList.add("Merlot");
                wineList.add("Pinot Noir");
            }else if(wineType.equals("white")){
                wineList.add("Chardonnay");
            }
            return wineList;
        }


        public String wineSearchByCountry() {
            return null;
        }

        @PostConstruct
        public void initializeCountryWineList(){
            countryMap.put("Australia", "Sauvignon Blanc");
            countryMap.put("Australia", "Grenache");
            countryMap.put("France","Gewurztraminer");
            countryMap.put("France","Bordeaux");
            System.out.println("SearchFacadeBean just CREATED... and country wine list FILLED");
        }

        @PreDestroy
        public void destroyWineList() {
            countryMap.clear();
            System.out.println("SearchFacadeBean is going to be DESTROYED... wine list is EMPTIED");
        }

        @AroundInvoke
        public Object timerLog(InvocationContext ctx) throws Exception{
            String beanClassName = ctx.getClass().getName();
            String businessMethodName = ctx.getMethod().getName();
            String target = beanClassName + "." + businessMethodName ;
            long startTime = System.currentTimeMillis();
            System.out.println("Invoking: " + target);

            Object ob = null;

            try{
                ob = ctx.proceed();
            }finally{
                System.out.println ("Exiting" + target);
                long totalTime = System.currentTimeMillis() - startTime;
                System.out.println ("Business method" + businessMethodName +
                "in" + beanClassName + "takes" + totalTime + "ms to execute");
            }

            return ob;
        }


    }

Server Maven POM:

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>searchFacade</groupId>
  <artifactId>SearchFacadeSessionBean</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>ejb</packaging>

  <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- other plugin versions -->
        <version.compiler.plugin>3.1</version.compiler.plugin>
        <version.ejb.plugin>2.3</version.ejb.plugin>

        <!-- maven-compiler-plugin -->
        <maven.compiler.target>1.7</maven.compiler.target>
        <maven.compiler.source>1.7</maven.compiler.source>
  </properties>

  <!-- Define the version of WildFly's Java EE 7 APIs we want to use -->
  <!-- WildFly distributes a complete set of Java EE 7 APIs including a Bill 
  of Materials (BOM). A BOM specifies the versions of a "stack" (or a collection) 
  of artifacts. We use this here so that we always get the correct versions 
  of artifacts. Here we use the jboss-javaee-6.0 stack (you can read this as 
  the WildFly stack of the Java EE 7 APIs). You can actually use this stack with 
  any version of WildFly AS that implements Java EE 7, not just WildFly AS 7! -->
  <dependencyManagement>
    <dependencies>
        <dependency>
           <groupId>org.wildfly.bom</groupId>
           <artifactId>jboss-javaee-7.0-with-all</artifactId>
           <version>8.2.1.Final</version>
           <type>pom</type>
           <scope>import</scope>
        </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
  <!-- Import the Common Annotations API (JSR-250), we use provided scope 
            as the API is included in JBoss AS 7 -->
    <dependency>
        <groupId>org.jboss.spec.javax.annotation</groupId>
        <artifactId>jboss-annotations-api_1.1_spec</artifactId>
        <scope>provided</scope>
    </dependency>

  <!-- Import the EJB 3.1 API, we use provided scope as the API is included in JBoss AS 7 -->
    <dependency>
        <groupId>org.jboss.spec.javax.ejb</groupId>
        <artifactId>jboss-ejb-api_3.1_spec</artifactId>
        <version>1.0.0.Final</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.hibernate.javax.persistence</groupId>
        <artifactId>hibernate-jpa-2.0-api</artifactId>
        <version>1.0.1.Final</version>
    </dependency>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>7.0</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
        <!-- Compiler plugin enforces Java 1.7 compatibility and activates annotation 
                processors -->

         <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>${version.compiler.plugin}</version>
          <configuration>
            <source>${maven.compiler.source}</source>
            <target>${maven.compiler.target}</target>
            <excludes>
              <exclude>com/apress/ejb/chapter03/entities/*.java</exclude>
              <exclude>com/apress/ejb/chapter03/services/*.java</exclude>
            </excludes>
          </configuration>
    </plugin>
        <!-- JBoss AS plugin to deploy the application -->
        <plugin>
            <groupId>org.wildfly.plugins</groupId>
            <artifactId>wildfly-maven-plugin</artifactId>
            <version>1.1.0.Final</version>
            <configuration>
                <filename>${project.build.finalName}.jar</filename>
            </configuration>
        </plugin>
        <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-ejb-plugin</artifactId>
           <version>${version.ejb.plugin}</version>
           <configuration>
               <ejbVersion>3.1</ejbVersion>
               <!-- this is false by default -->
               <generateClient>true</generateClient>

           </configuration>

        </plugin>
    </plugins>
  </build>

</project>

当我部署到WildFly 8时,控制台中会显示以下两个绑定:

(1)
10:06:22,593 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named SearchFacade in deployment unit deployment "SearchFacadeSessionBean.jar" are as follows:

    java:global/SearchFacadeSessionBean/SearchFacade!com.apress.ejb.chapter02.business.SearchFacade
    java:app/SearchFacadeSessionBean/SearchFacade!com.apress.ejb.chapter02.business.SearchFacade
    java:module/SearchFacade!com.apress.ejb.chapter02.business.SearchFacade
    java:jboss/exported/SearchFacadeSessionBean/SearchFacade!com.apress.ejb.chapter02.business.SearchFacade
    java:global/SearchFacadeSessionBean/SearchFacade!com.apress.ejb.chapter02.business.SearchFacadeLocal
    java:app/SearchFacadeSessionBean/SearchFacade!com.apress.ejb.chapter02.business.SearchFacadeLocal
    java:module/SearchFacade!com.apress.ejb.chapter02.business.SearchFacadeLocal


(2)
6:22,609 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-3) JNDI bindings for session bean named SearchFacade in deployment unit deployment "SearchFacadeSessionBean-0.0.1-SNAPSHOT.jar" are as follows:

    java:global/SearchFacadeSessionBean-0.0.1-SNAPSHOT/SearchFacade!com.apress.ejb.chapter02.business.SearchFacade
    java:app/SearchFacadeSessionBean-0.0.1-SNAPSHOT/SearchFacade!com.apress.ejb.chapter02.business.SearchFacade
    java:module/SearchFacade!com.apress.ejb.chapter02.business.SearchFacade
    java:jboss/exported/SearchFacadeSessionBean-0.0.1-SNAPSHOT/SearchFacade!com.apress.ejb.chapter02.business.SearchFacade
    java:global/SearchFacadeSessionBean-0.0.1-SNAPSHOT/SearchFacade!com.apress.ejb.chapter02.business.SearchFacadeLocal
    java:app/SearchFacadeSessionBean-0.0.1-SNAPSHOT/SearchFacade!com.apress.ejb.chapter02.business.SearchFacadeLocal
    java:module/SearchFacade!com.apress.ejb.chapter02.business.SearchFacadeLocal

令我惊讶的是,我没有在任何绑定中看到实现类&#34; SearchFacadeBean&#34; 。它仅显示接口(SearchFacade,SearchFacadeLocal)。

客户申请:

//Client POM

    <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>sessionBeanClient</groupId>
      <artifactId>SearchFacadeSessionBeanClient</artifactId>
      <version>0.0.1-SNAPSHOT</version>

          <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

            <!-- JBoss dependency versions -->
            <version.wildfly>8.1.0.Final</version.wildfly>
            <version.jboss.spec.javaee.7.0>1.0.0.Final</version.jboss.spec.javaee.7.0>

            <!-- other plugin versions -->
            <version.compiler.plugin>3.1</version.compiler.plugin>
            <version.ejb.plugin>2.3</version.ejb.plugin>

            <!-- maven-compiler-plugin -->
            <maven.compiler.target>1.7</maven.compiler.target>
            <maven.compiler.source>1.7</maven.compiler.source>
          </properties>

          <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.jboss.spec</groupId>
                    <artifactId>jboss-javaee-7.0</artifactId>
                    <version>${version.jboss.spec.javaee.7.0}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <dependency>
                    <groupId>org.wildfly</groupId>
                    <artifactId>wildfly-ejb-client-bom</artifactId>
                    <version>${version.wildfly}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>

        <dependencies>

            <!-- Business Interfaces of the server EJB. -->
            <dependency>
                <groupId>searchFacade</groupId>
                <artifactId>SearchFacadeSessionBean</artifactId>
                <type>ejb</type>
                <version>${project.version}</version>
            </dependency>

            <!-- Import the transaction spec API, we use runtime scope because we aren't 
                using any direct reference to the spec API in our client code -->
            <dependency>
                <groupId>org.jboss.spec.javax.transaction</groupId>
                <artifactId>jboss-transaction-api_1.2_spec</artifactId>
                <scope>runtime</scope>
            </dependency>

            <!-- Import the EJB 3.1 API, we use runtime scope because we aren't using 
                any direct reference to EJB spec API in our client code -->
            <dependency>
                <groupId>org.jboss.spec.javax.ejb</groupId>
                <artifactId>jboss-ejb-api_3.2_spec</artifactId>
                <scope>runtime</scope>
            </dependency>

            <!-- JBoss EJB client API jar. We use runtime scope because the EJB client 
                API isn't directly used in this example. We just need it in our runtime classpath -->
            <dependency>
                <groupId>org.jboss</groupId>
                <artifactId>jboss-ejb-client</artifactId>
                <scope>runtime</scope>
            </dependency>

            <!-- client communications with the server use XNIO -->
            <dependency>
                <groupId>org.jboss.xnio</groupId>
                <artifactId>xnio-api</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.jboss.xnio</groupId>
                <artifactId>xnio-nio</artifactId>
                <scope>runtime</scope>
            </dependency>

            <!-- The client needs JBoss remoting to access the server -->
            <dependency>
                <groupId>org.jboss.remoting</groupId>
                <artifactId>jboss-remoting</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.jboss</groupId>
                <artifactId>jboss-remote-naming</artifactId>
                <scope>runtime</scope>
            </dependency>

            <!-- Remote EJB accesses can be secured -->
            <dependency>
                <groupId>org.jboss.sasl</groupId>
                <artifactId>jboss-sasl</artifactId>
                <scope>runtime</scope>
            </dependency>

            <!-- data serialization for invoking remote EJBs -->
            <dependency>
                <groupId>org.jboss.marshalling</groupId>
                <artifactId>jboss-marshalling-river</artifactId>
                <scope>runtime</scope>
            </dependency>
        </dependencies>    

        <build>
            <plugins>
                <!-- Compiler plugin enforces Java 1.7 compatibility and activates annotation processors -->
                 <plugin>
                     <artifactId>maven-compiler-plugin</artifactId>
                     <version>${version.compiler.plugin}</version>
                     <configuration>
                         <source>${maven.compiler.source}</source>
                         <target>${maven.compiler.target}</target>
                     </configuration>
                 </plugin>
                 <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>exec-maven-plugin</artifactId>
                    <version>1.5.0</version> 
                    <!-- version>${version.exec.plugin}</version--> 
                    <executions>
                        <execution>
                            <goals>
                                <!-- goal>exec</goal-->
                                <goal>java</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <executable>java</executable>
                        <workingDirectory>${project.build.directory}/exec-working-directory</workingDirectory>

                        <mainClass>searchFacadeClient.Client</mainClass>



                    </configuration>
                </plugin>

            </plugins>
        </build>

    </project>

客户类:

package searchFacadeClient;

public class ClientUtility {

        private static Context initialContext;
        private static final String PKG_INTERFACES = "org.jboss.ejb.client.naming";

        public static Context getInitialContext() {
            if (initialContext == null) {
                //Properties properties = new Properties();
                Hashtable properties = new Hashtable();
                properties.put(Context.URL_PKG_PREFIXES, PKG_INTERFACES);
                try {
                    initialContext = new InitialContext(properties);
                } catch (NamingException e) {
                    // TODO Auto-generated catch block
                    System.out.println("THERE IS A HUGE RPROBLEM..........");
                    e.printStackTrace();
                }
            }
            return initialContext;
        }

    }




package searchFacadeClient;

public class Client {

    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        System.out.print("Enter wine Type(red/white): ");
        //System.out.println("Enter 's' to EXIT: ");
        String wineName = reader.readLine();
        // Invoke a stateless bean
        try {
            List<String> wines = getWines(wineName);
            for(String wine: wines){
                System.out.println(wine);
            }
        } catch (NamingException e) {
            System.out.println("Naming Exception: ");
            e.printStackTrace();
        }
    }

    private static List<String> getWines(String wineType)throws NamingException{
        SearchFacade searchWines = doLookup();

        return searchWines.wineSearch(wineType);
    }

    private static SearchFacade doLookup() {
        Context context = null;
        SearchFacade bean = null;
        try {
            // 1. Obtaining Context
            context = ClientUtility.getInitialContext();
            // 2. Generate JNDI Lookup name
            String lookupName = getLookupName(); System.out.println("Lookup name: " + lookupName);
            // 3. Lookup and cast
            bean = (SearchFacade) context.lookup(lookupName);


        } catch (NamingException e) {
            e.printStackTrace();
        }
        return bean;
    }


    private static String getLookupName() {
        /*
         * The app name is the EAR name of the deployed EJB without .ear suffix.
         * Since we haven't deployed the application as a .ear, the app name for
         * us will be an empty string
         */
        String appName = "";

        /*
         * The module name is the JAR name of the deployed EJB without the .jar
         * suffix.
         */
        String moduleName = "SearchFacadeSessionBean-0.0.1-SNAPSHOT"; 

        /*
         * AS7 allows each deployment to have an (optional) distinct name. This
         * can be an empty string if distinct name is not specified.
         */
        String distinctName = "";

        // The EJB bean implementation class name
        String beanName = "SearchFacadeBean";

        // Fully qualified remote interface name
        final String interfaceName = "com.apress.ejb.chapter02.business.SearchFacade";

        // Create a look up string name
        String name = "ejb:" + appName + "/" + moduleName + "/" + distinctName
                + "/" + beanName + "!" + interfaceName;

        /*String name = "java:" + appName + "/" + moduleName + "/" + distinctName
                + "/" + beanName + "!" + interfaceName;*/

       // return name;
        return "ejb:SearchFacadeSessionBean/SearchFacade!com.apress.ejb.chapter02.business.SearchFacade";
    }

}

如果您查看有关&#34; name&#34; 变量的最后几条陈述,其中一些陈述在评论中。当我返回&#34; name&#34; 变量中的值时,我得到: ejb:/SearchFacadeSessionBean-0.0.1-SNAPSHOT//SearchFacadeBean!com.apress.ejb。 chapter02.business.SearchFacade 我知道这是错的。

那里不应该有两个斜线,但我认为我已经给出了上述变量的所有正确值。所以我决定把这个&#34;名称&#34;在评论中变量并尝试从服务器控制台进行一些出价。因此,在运行客户端应用程序时,您在下面看到的结果(例外)部分是由于"getLookupName()"函数返回字符串。

当我运行客户端应用程序来调用Beans时,我得到以下异常:输入wine类型(红色/白色):

java.lang.reflect.InvocationTargetException
    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.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:294)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassCastException: org.jboss.ejb.client.naming.ejb.EjbNamingContext cannot be cast to com.apress.ejb.chapter02.business.SearchFacade
    at searchFacadeClient.Client.doLookup(Client.java:47)
    at searchFacadeClient.Client.getWines(Client.java:33)
    at searchFacadeClient.Client.main(Client.java:22)

jboss.ejb.client.properties 文件是:

remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=localhost
#remote.connection.default.port = 4447
remote.connection.default.port = 8080
  remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false

我认为可能导致问题的领域是:

(1)服务器控制台日志中的绑定不会显示有关Bean实现类的任何信息。

(2)我认为实施类没有部署到服务器

(3)问题也可能来自SERVER和客户端POM,但不确切知道在哪里,可能会遗漏一些东西。

(4)另一个主要问题是我尝试使用MAVEN_WILDFLY_PLUGIN部署应用程序,但我在控制台中收到以下错误::

[ERROR] Failed to execute goal org.wildfly.plugins:wildfly-maven-plugin:1.1.0.Final:deploy (default-cli) on project SearchFacadeSessionBean: Failed to execute goal deploy. java.net.ConnectException: WFLYPRT0053: Could not connect to http-remoting://localhost:9990. The connection failed: Connection refused: no further information -> [Help 1]

所以我决定使用eClipse中的服务器控制台视图部署它,方法是右键单击WildFly并选择添加/删除。我不知道以这种方式部署它是否会导致问题。

0 个答案:

没有答案