Как вызвать EJB из другого приложения на том же сервере?

У меня есть пример клиента java SE, который работает на рабочем столе (код ниже). Но у меня есть доступ к WebSphere, который называется EJB. Как переписать приведенный ниже код для работы в WebSphere? (Когда я оставляю этот код как есть, программа работает, но я думаю, что это можно сделать проще и понятнее)

Основной метод:

WSConn connection = new WSConn();
final Plan plan = connection.getPlanBean();
com.ibm.websphere.security.auth.WSSubject.doAs(connection.getSubject(), new java.security.PrivilegedAction<Object>() {
public Object run() {
try {
    // App logic
} catch (Throwable t) {
    System.err.println("PrivilegedAction - Error calling EJB: " + t);
t.printStackTrace();
   }
     return null;
  }
}); // end doAs

Класс WSConn:

public class WSConn {
    private static final String INITIAL_CONTEXT_FACTORY = "com.ibm.websphere.naming.WsnInitialContextFactory";
    private static final String JAAS_MODULE = "WSLogin";
    private static final String MODEL_EJB_NAME_LONG = "ejb/com/ibm/ModelHome";
    private static final String PLAN_EJB_NAME_LONG = "ejb/com/ibm/PlanHome";
    private Subject subject;
    private InitialContext initialContext;
    private String serverName;
    private String serverPort;
    private String uid;
    private String pwd;
    private String remoteServerName;
    private Model modelBean;
    private Plan planBean;
    public WSConn() {
        Properties props = new Properties();
        try {
            props.load(WSConn.class.getClassLoader().getResourceAsStream("WSConn.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        serverName = props.getProperty("WSConn.serverName");
        serverPort = props.getProperty("WSConn.serverPort");
        uid = props.getProperty("WSConn.userID");
        pwd = props.getProperty("WSConn.password");
        remoteServerName = props.getProperty("WSConn.remoteServerName");
    }

    private void init() {
        if (subject == null || initialContext == null) {
            subject = login();
        }
    }

    private Subject login() {

        Subject subject = null;
        try {
            LoginContext lc = null;

            // CRATE LOGIN CONTEXT
            Hashtable<String, String> env = new Hashtable<String, String>();
            env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
            env.put(Context.PROVIDER_URL, "corbaloc:iiop:" + serverName + ":" + serverPort);

            initialContext = new InitialContext(env);

            // Just to test the connection
            initialContext.lookup("");

            lc = new LoginContext(JAAS_MODULE, new WSCallbackHandlerImpl(uid, pwd));
            lc.login();

            subject = lc.getSubject();


        } catch (javax.naming.NoPermissionException exc) {
            System.err.println("[WSConn] - Login Error: " + exc);

        } catch (Exception exc) {
            System.err.println("[WSConn] - Error: " + exc);
        }
        return subject;
    }

    public wModel getModelBean() {
        if (modelBean == null) {
            init();
            modelBean = (wModel) com.ibm.websphere.security.auth.WSSubject.doAs(subject,
                    new java.security.PrivilegedAction<wModel>() {
                        public wModel run() {
                            wModel session = null;
                            try {
                                Object o = initialContext.lookup(MODEL_EJB_NAME_LONG);
                                wModelHome home = (wModelHome) PortableRemoteObject.narrow(o, wModelHome.class);

                                if (home != null) {
                                    session = home.create(remoteServerName);
                                }

                            } catch (Exception exc) {
                                System.err.println("Error getting model bean: " + exc);
                            }
                            return session;
                        }
                    }); // end doAs
        }

        return modelBean;
    }

    public wPlan getPlanBean() {
        if (planBean == null) {
            init();
            planBean = (wPlan) com.ibm.websphere.security.auth.WSSubject.doAs(subject,
                    new java.security.PrivilegedAction<wPlan>() {
                        public wPlan run() {
                            wPlan session = null;
                            try {
                                Object o = initialContext.lookup(PLAN_EJB_NAME_LONG);
                                wPlanHome home = (wPlanHome) PortableRemoteObject.narrow(o, wPlanHome.class);

                                if (home != null) {
                                    session = home.create(remoteServerName);
                                }

                            } catch (Exception exc) {
                                System.err.println("Error getting plan bean: " + exc);
                            }
                            return session;
                        }
                    }); // end doAs
        }

        return planBean;
    }

    public Subject getSubject() {
        if (subject == null) {
            init();
        }

        return subject;
    }
}

person moral    schedule 26.03.2015    source источник


Ответы (2)


Как указано в другом ответе, классический механизм заключается в поиске и сужении домашнего интерфейса.

Получить исходный контекст

final InitialContext initialContext = new InitialContext();

Поиск дома по имени jndi, указав полное имя jndi

Object obj = initialContext.lookup("ejb/com/ibm/tws/conn/plan/ConnPlanHome");

или вы можете создать электронную ссылку в своем WAR и использовать java:comp/env/yourname

Затем сузьте дом до класса домашнего интерфейса

ConnPlanHome planHome = (ConnPlanHome)PortableRemoteObject.narrow(obj, ConnPlanHome.class);

а затем создайте удаленный интерфейс EJB

ConnPlan plan = planHome.create();

Информация о вызовах должна работать для распространяемого IBM Workload Scheduler. Для IBM Workload Scheduler z/OS имя JNDI и имена классов отличаются:

final InitialContext initialContext = new InitialContext();
String engineName = "XXXX";
Object obj = initialContext.lookup("ejb/com/ibm/tws/zconn/plan/ZConnPlanHome");
ZConnPlanHome planHome = (ZConnPlanHome)PortableRemoteObject.narrow(obj, ZConnPlanHome.class);
ZConnPlan plan = planHome.create(engineName);

Учетные данные пользователя передаются от клиента к движку, клиент должен быть аутентифицирован, иначе движок отклонит запрос.

person Franco Mossotto    schedule 01.06.2016
comment
Спасибо, Франко отлично работает. Немного деталей: сначала вы должны авторизовать пользователя (например, с помощью формы входа и j_security_check) и добавить небольшую модификацию: String engineName = XXXX; План ZConnPlan = planHome.create(engineName); - person moral; 03.06.2016
comment
Спасибо за ваш отзыв. Я отредактировал ответ, чтобы включить ваш комментарий - person Franco Mossotto; 06.06.2016

Если вы пытаетесь получить доступ к EJB из класса POJO, то нет ничего проще, чем поиск+узкий поиск. Однако, если POJO включен в приложение (EAR или WAR), вы можете объявить и найти ссылку EJB (java:comp/ejb/myEJB), и тогда контейнер будет выполнять узкий, а не ваш код. Если вы измените свой код на управляемый класс, такой как сервлет, другой EJB или компонент CDI, тогда вы можете использовать @EJB инъекцию, и тогда вам даже не потребуется поиск.

person Brett Kail    schedule 27.03.2015