Hot questions for Using Enterprise JavaBeans in websphere 8

Question:

I have a requirement where I'm asked to load both remote and local EJBs with a JNDI lookup, so without the @EJB annotation.

My EJB is defined as follows:

@Remote
public interface MyObjectInterfaceRemote extends MyObjectInterface {

}

@Local
public interface MyObjectInterfaceLocal extends MyObjectInterface {

}

public interface MyObjectInterface {
    // A bunch of methods which both remote and local ejbs will inherit
}

@Remote(MyObjectInterfaceRemote.class)
@Local(MyObjectInterfaceLocal.class)
public class MyObjectEJB implements MyObjectInterfaceLocal, MyObjectInterfaceRemote {
    //implementation of all methods inherited from MyObjectInterface.
}

I'm using this code to lookup the remote EJB:

private MyObjectInterfaceRemote getEJB() throws NamingException {
    InitialContext context = new InitialContext();
    return (MyObjectInterfaceRemote) context.lookup(MyObjectInterfaceRemote.class.getName());
}

It works fine, but if I make another method like this:

private MyObjectInterfaceLocal getLocalEJB() throws NamingException {
    InitialContext context = new InitialContext();
    return (MyObjectInterfaceLocal) context.lookup(MyObjectInterfaceLocal.class.getName());
}

I get

javax.naming.NameNotFoundException: 
Context: Backslash-PCNode03Cell/nodes/Backslash-PCNode03/servers/server1, 
name: MyObjectInterfaceLocal: First component in name MyObjectInterfaceLocal not found. 
[Root exception is org.omg.CosNaming.NamingContextPackage.NotFound: 
IDL:omg.org/CosNaming/NamingContext/NotFound:1.0]
[...]

What am I missing? Do I have to use something different to lookup a local ejb?

Note: If I use

@EJB
MyObjectInterfaceLocal ejb;

The local ejb gets succesfully loaded.


Answer:

Have you tried below code?

context.lookup("ejblocal:"+MyObjectInterfaceLocal.class.getName())

Webshpere uses different default binding pattern for remote and local interfaces.

Question:

I am trying to deploy EAR file on WebShpere 8.5 and I keep getting this error:

com.ibm.ejs.container.EJBConfigurationException: The BackendBE.war Enterprise JavaBeans (EJB) module does not have any enterprise beans configured.

I add backendBE.war to the EAR project I want to install on my server, the error appears after trying to start the server.

Full error log:

com.ibm.ejs.container.EJBConfigurationException: The BackendBE.war Enterprise JavaBeans (EJB) module does not have any enterprise beans configured.
       at com.ibm.ws.ejbcontainer.runtime.AbstractEJBRuntime.startModule(AbstractEJBRuntime.java:605)
       at com.ibm.ws.ejbcontainer.runtime.SharedEJBRuntimeImpl.startModule(SharedEJBRuntimeImpl.java:336)
       at com.ibm.ws.runtime.component.EJBContainerImpl.start(EJBContainerImpl.java:3576)
       at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:1175)
       at com.ibm.ws.runtime.component.DeployedApplicationImpl.fireDeployedObjectStart(DeployedApplicationImpl.java:1370)
       at com.ibm.ws.runtime.component.DeployedModuleImpl.start(DeployedModuleImpl.java:639)
       at com.ibm.ws.runtime.component.DeployedApplicationImpl.start(DeployedApplicationImpl.java:968)
       at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplication(ApplicationMgrImpl.java:774)
       at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:2182)
       at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:445)
       at com.ibm.ws.runtime.component.CompositionUnitImpl.start(CompositionUnitImpl.java:123)
       at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:388)
       at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.access$500(CompositionUnitMgrImpl.java:116)
       at com.ibm.ws.runtime.component.CompositionUnitMgrImpl$CUInitializer.run(CompositionUnitMgrImpl.java:994)
       at com.ibm.wsspi.runtime.component.WsComponentImpl$_AsynchInitializer.run(WsComponentImpl.java:502)
       at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1862)

If there is more code needed, please comment below.

Thanks.


Answer:

This exception occurs when a WAR module contains an ejb-jar.xml file that does not define any EJBs. When an ejb-jar.xml file is present, it must define at least one EJB, or there must be at least one EJB defined via annotations (like @Stateless) and the ejb-jar.xml and web.xml files must not container metadata-complete=true.

Question:

I’m developing Java EE application which has many integrations with other services. All integrations are done over remote EJB beans. So currently I have 3 or 4 EJB projects which are deployed as EARs on WebSphere to serve as mocks (since I don’t have access to real services in my development environment). What I want to do is to combine all of those mocks into one EAR package so I can have a single configuration page for mocks (return values, exceptions, etc.). So I made generalMock.ear application. The problem is now that EJB binding name is different than before.

For example the real application uses following binding name:

binding-name="java:global/company-app-calculator-ear/company-app-calculator-ejb/CalculatorSb!com.company.beans.app.calculator.CalculatorSbRemote" 

But now the binding name looks like this:

binding-name="java:global/general-mock-ear/company-app-calculator-ejb/CalculatorSb!com.company.beans.app.calculator.CalculatorSbRemote" 

Is there a way to change the global binding name? I have tried to create file "ibm-ejb-jar-bnd.xml" and add it to EJB mock’s META-INF folder where I wanted to change the binding name but I’s not working. Here is the content of my "ibm-ejb-jar-bnd.xml" configuration file:

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar-bnd xmlns="http://websphere.ibm.com/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-bnd_1_0.xsd"
             version="1.0">

    <session name="CalculatorSb">
        <interface
                binding-name="java:global/company-app-calculator-ear/company-app-calculator-ejb/CalculatorSb!com.company.beans.app.calculator.CalculatorSbRemote"
                class="com.company.beans.app.calculator.CalculatorSbRemote"/>
    </sescomon>
</ejb-jar-bnd>

I'm using IBM WebSphere 8.5 running on Java 1.6 EE.


Answer:

The format of the java: names are defined by the Java EE and EJB specifications for portability across providers. In general, the specification does not provide a way to override these names, nor does WebSphere.

The <interface> element in the ibm-ejb-jar-bnd.xml file may be used in traditional WebSphere to define where an EJB is bound in the server context root (not a java: location), in addition to the java: location. The binding-name value must not start with java:.

Basically, you would need to change the name of your mock EAR, or set the application name in application.xml, but it seems that would only solve the problem for one of the EJB modules in your mock application.

Perhaps consider using EJB references instead of performing direct lookups in java:global. This would allow your application to always lookup the EJB reference name, which would never change. You would just need to bind the EJB reference name to either the real name or mock name depending on the environment.

Question:

I have deployed a secure ejb on machine1, when I run the client code on the same machine, it works fine. But when I run the client code on any other machine it throws an error. which is pasted below.

In the error it can be seen that its not taking the ip: that is provided but instead it looks in the client machine itself. Where is the problem is it in the client code or am I missing some settings in WebSphere.

package org.was.tutorial.security.client;

import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;

import org.was.tutorial.security.bean.Calculator;

public class Client
{
   public static void main(String[] args) throws Exception
   {
      //Establish the proxy with an incorrect security identity
      Properties env = new Properties();

      //username and password
      //String username="teacher1";
      //String password="teacher";


      String username="student1";
      String password="student";

      //setting up environment properties..
      env.setProperty(Context.SECURITY_PRINCIPAL, username);
      env.setProperty(Context.SECURITY_CREDENTIALS, password);
      env.setProperty(javax.naming.Context.PROVIDER_URL, "iiop://10.94.13.18:2809");
      env.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");
      InitialContext ctx = new InitialContext(env);
      //javax.rmi.PortableRemoteObject.narrow(ctx.lookup("CalculatorBean/remote"), Calculator.class);

      Calculator calculator =null;
      try{
      calculator = (Calculator)javax.rmi.PortableRemoteObject.narrow(ctx.lookup("CalculatorBean/remote"), Calculator.class);
      if(calculator==null){
          System.out.println("This is not going anywhere");
      }else
          System.out.println("Good. we made a progress.");

      }catch (Exception e) {
          e.printStackTrace();
      }

      System.out.println("User "+username);
      System.out.println("Addition can be performed by  all");

      try
      {
         System.out.println("1 + 1 = " + calculator.add(1, 1));
      }
      catch (Exception ex)
      {
         System.out.println("Saw expected SecurityException: " + ex.getMessage());
      }

      System.out.println("Subtraction- can be performed by students only.");
      try
      {
         System.out.println("16- 4 ="+calculator.subtract(16, 4));
      }catch (Exception  ex)
      {
         System.out.println(ex.getMessage());
      }

      System.out.println("Division- can be performed by teachers only.");      
      try
      {
         System.out.println("16/4 ="+calculator.divide(16, 4));
      }catch (Exception  ex)
      {
         System.out.println(ex.getMessage());
      }
     ///cool


   }
}

Error:

Exception in thread "P=13152:O=0:CT" javax.naming.NamingException: Error getting WsnNameService properties [Root exception is org.omg.CORBA.TRANSIENT: initial and forwarded IOR inaccessible  vmcid: IBM  minor code: E07  completed: No]
at com.ibm.ws.naming.util.WsnInitCtxFactory.mergeWsnNSProperties(WsnInitCtxFactory.java:1552)
at com.ibm.ws.naming.util.WsnInitCtxFactory.getRootContextFromServer(WsnInitCtxFactory.java:1042)
at com.ibm.ws.naming.util.WsnInitCtxFactory.getRootJndiContext(WsnInitCtxFactory.java:962)
at com.ibm.ws.naming.util.WsnInitCtxFactory.getInitialContextInternal(WsnInitCtxFactory.java:614)
at com.ibm.ws.naming.util.WsnInitCtx.getContext(WsnInitCtx.java:128)
at com.ibm.ws.naming.util.WsnInitCtx.getContextIfNull(WsnInitCtx.java:765)
at com.ibm.ws.naming.util.WsnInitCtx.lookup(WsnInitCtx.java:164)
at com.ibm.ws.naming.util.WsnInitCtx.lookup(WsnInitCtx.java:179)
at javax.naming.InitialContext.lookup(InitialContext.java:423)
at com.temenos.services.ofsconnector.ejb.IntegrationFrameworkServiceClient.main(IntegrationFrameworkServiceClient.java:50)
Caused by: org.omg.CORBA.TRANSIENT: initial and forwarded IOR inaccessible  vmcid: IBM  minor code: E07  completed: No
at com.ibm.rmi.corba.ClientDelegate.createRequest(ClientDelegate.java:1109)
at com.ibm.CORBA.iiop.ClientDelegate.createRequest(ClientDelegate.java:1463)
at com.ibm.rmi.corba.ClientDelegate.createRequest(ClientDelegate.java:1001)
at com.ibm.CORBA.iiop.ClientDelegate.createRequest(ClientDelegate.java:1429)
at com.ibm.rmi.corba.ClientDelegate.request(ClientDelegate.java:1618)
at com.ibm.CORBA.iiop.ClientDelegate.request(ClientDelegate.java:1385)
at org.omg.CORBA.portable.ObjectImpl._request(ObjectImpl.java:458)
at com.ibm.WsnBootstrap._WsnNameServiceStub.getProperties(_WsnNameServiceStub.java:38)
at com.ibm.ws.naming.util.WsnInitCtxFactory.mergeWsnNSProperties(WsnInitCtxFactory.java:1549)
... 9 more
Caused by: org.omg.CORBA.COMM_FAILURE: CONNECT_FAILURE_ON_SSL_CLIENT_SOCKET - JSSL0130E: java.io.IOException: Signals that an I/O exception of some sort has occurred.  Reason:  Connection refused: connect Remote Host: 127.0.0.1  Remote Port: 9403  vmcid: 0x49421000  minor code: 80  completed: No
at com.ibm.ws.security.orbssl.WSSSLClientSocketFactoryImpl.tryToCreateConnectedSSLSocket(WSSSLClientSocketFactoryImpl.java:357)
at com.ibm.ws.security.orbssl.WSSSLClientSocketFactoryImpl.createSSLSocket(WSSSLClientSocketFactoryImpl.java:219)
at com.ibm.ws.orbimpl.transport.WSSSLTransportConnection.createSocket(WSSSLTransportConnection.java:236)
at com.ibm.CORBA.transport.TransportConnectionBase.connect(TransportConnectionBase.java:348)
at com.ibm.ws.orbimpl.transport.WSTransport$1.run(WSTransport.java:503)
at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:118)
at com.ibm.ws.orbimpl.transport.WSTransport.getConnection(WSTransport.java:500)
at com.ibm.CORBA.transport.TransportBase.getConnection(TransportBase.java:181)
at com.ibm.rmi.iiop.TransportManager.get(TransportManager.java:97)
at com.ibm.rmi.iiop.GIOPImpl.getConnection(GIOPImpl.java:134)
at com.ibm.rmi.iiop.GIOPImpl.locate(GIOPImpl.java:230)
at com.ibm.rmi.corba.ClientDelegate.locate(ClientDelegate.java:1696)
at com.ibm.rmi.corba.ClientDelegate._createRequest(ClientDelegate.java:1721)
at com.ibm.rmi.corba.ClientDelegate.createRequest(ClientDelegate.java:1023)
at com.ibm.rmi.corba.ClientDelegate.createRequest(ClientDelegate.java:1105)
... 17 more

Update

I have created the node and profile using the following script:

File1:setUpEnv.bat

set WAS_HOME=C:\IBM\WebSphere\AppServer
set HOST_NAME=localhost
set PROFILE_NAME=AppSrv01

set NODE_NAME=%PROFILE_NAME%Node01
set CELL_NAME=%NODE_NAME%Cell  
set SERVER_NAME=server1

set DMGR_USER=user1
set DMGR_PASSWORD=123456
set DMGR_HOST=localhost
set DMGR_PORT=8879

File2:

CALL ./setUpEnv.bat
set WAS_HOME=C:\IBM\WebSphere\AppServer
CALL %WAS_HOME%\bin\manageprofiles.bat -create -profileName %PROFILE_NAME% -       profilePath %WAS_HOME%\profiles\%PROFILE_NAME% -templatePath %WAS_HOME%\profileTemplates\default -serverName %SERVER_NAME% -cellName %CELL_NAME% -nodeName %NODE_NAME% -hostName %HOST_NAME% -enableAdminSecurity true -adminUserName %DMGR_USER% -adminPassword %DMGR_PASSWORD%

Answer:

The 9403 is correct port for RMI/IIOP SSL communication (CSIV2_ SSL_ SERVERAUTH_ LISTENER_ ADDRESS). It might happen that you incorrectly installed WAS using localhost, and it sends to the client redirection for the localhost instead for its host name.

Double check WAS configuration for example via web console, in the Server -> Administration -> ports section.

If you installed WAS using localhost, you will either have to change host, or recreate provile (the second might be easier if you are a new to WAS).

Question:

I'm getting problems trying to call a remote service deployed in an EAR from another EAR. I do not specify any names for my EJB, no matter they are @Local or @Remote and so just use annotation and inject it via @EJB.

This is what i have:

  • EAR A/

    • lib/any lib jar (including API jar for remote service B)
    • war
    • ejb module(s) with service A calling remote service B
  • EAR B/

    • lib/any API lib jar
    • ejb module with service B

Additional information: Service B implement both @Local and @Remote interfaces, and Service A inject Service B with Remote interface via:

@EJB private MyRemoteInterface remoteService;

This structure works perfectly fine with jboss server, but with websphere (8.5.5.1) one i must bind names onto my remote EJB. If do not add bindings on both EARs (i did it though admin console directly not to have to edit ejb-jar.xml) then my remote bean is not resolved at runtime. Of course, i have to make it work with WAS, else i won't not post :)

My question: is that normal to be forced to name remote EJB with WebSphere or is it a regression (from any previous version) ? I'm expecting the injection @EJB on remote beans to works with automatic resolution on types, but maybe i'm wrong somewhere ?

Solution: Because lookup must be done to make the resolution work, i decided to add the lookup configuration part onto the client ejb-jar.xml file(s). This is done automatically by maven plugin execution, with lookup name based on remote interface full name (package included) as this is the default binding WebSphere use if nothing is specified in EJB implementation.

I've chosen this solution for two reasons:

  • i don't want to do the lookup in my code (duplicate code with no interest)
  • i need to make it automatic and transparent for other developers

Thanks bkail for the answer.


Answer:

This is working as expected for WebSphere Application Server, and it is not a regression. The javadoc only requires automatic binding for @EJB when the type is within the same application:

If no explicit linking information is provided and there is only one session bean within the same application that exposes the matching client view type, by default the EJB dependency resolves to that session bean.

Question:

We are seeing very weird issue in our environment.

We used to deploy an Application using WebSphere Admin console. Basically this one is an EAR file and during the deployment we used to specify "Database type" as blank in "Provide option to perform EJB Deploy option screen" and in next step we used to choose "MSSQLSERVER_V2005_1" as a backend id.

We are doing this because of following "If you specify a database type, previously defined backend IDs for all of the EJB modules are overwritten by the chosen database type. To enable backend IDs for individual EJB modules, select the empty choice to set the database type to null."

Ref : http://www-01.ibm.com/support/knowledgecenter/SSAW57_8.0.0/com.ibm.websphere.nd.doc/info/ae/ae/urun_rapp_ejbdeploy.html

Last time some one shutdown the whole server(physical box) and after that we started getting following exceptions in the logs WSRelationalR I DSRA8210I: The database product name Microsoft SQL Server may not exactly match with the database represented by the backend ID (DB2UDBNT).

To resolve this issue we tried to do following but issue stands unresolved 1. Stop start the server(JVM) 2. Stop start the Application

To resolve the issue we redeploy the whole application.

We want to find out the exact reason of this one. Any input or thoughts on the same?

Environment information is as follows WebSphere Application Server ND 8.0.0.9 Windows 2008 R2 Microsoft SQL Server 2012


Answer:

You can only specify the backend ID during application installation or update. You cannot select a backend ID after the application is installed onto a server. So you would need to reinstall the application.

Check these pages for more details:

Since the default backend ID is DB2UDB_V81, maybe someone by accident updated application using the shortcut path, without specifying backend (does you app provide many backends?)