Вызов EJB в JBoss из Tomcat и передача объекта в качестве аргумента - PullRequest
2 голосов
/ 23 августа 2009

У меня есть следующий класс EJB, созданный в приложении, работающем в JBoss 5

</p> <pre><code>public interface ISlaveServer { public String getId(); public String getName(); } @Remote public interface IMasterServer { public String getId(); public void addSlave(ISlaveServer slaveServer); public void removeSlave(ISlaveServer slaveServer); } @Stateless @RemoteBinding(jndiBinding = "MasterServer") public class MasterServer implements IMasterServer, Serializable { UUID id = UUID.randomUUID().toString(); public String getId() { return id.toString(); } public void addSlave(ISlaveServer slaveServer) { ... } public void removeSlave(ISlaveServer slaveServer) { ... } }

У меня есть следующий класс, созданный в приложении, запущенном в Tomcat 6

</p> <pre><code>public static class SlaveServer implements ISlaveServer, Serializable { UUID id = UUID.randomUUID().toString(); public String getId() { return id.toString(); } public String getName() { return "SlaveServer"; } }

Наконец, у меня есть следующий код, также работающий в приложении на основе Tomcat ... </p> <pre><code> Properties properties = new Properties(); properties.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory"); properties.put("java.naming.factory.url.pkgs", "org.jboss.naming.client"); properties.put("java.naming.provider.url", "jnp://localhost:1099"); try { Context ctx = new InitialContext(properties); IMasterServer masterServer = (IMasterServer) ctx.lookup("MasterServer"); String masterId = masterServer.getId(); masterServer.addVideoServer(new SlaveServer()); } catch(NamingException e) { e.printStackTrace(); }

Все работает нормально до звонка на

</p> <pre><code>masterServer.addVideoServer(new SlaveServer());

, когда я получаю следующее исключение ...

java.lang.ClassNotFoundException: org.test.SlaveServerTest $ SlaveServer (без диспетчера безопасности: загрузчик классов RMI отключен)

Из того, что я могу сказать, это исключение может происходить с удаленного сервера JBoss, потому что удаленные вызовы работают (masterServer.getId () работает нормально). Просто вызов, по которому я передаю локально реализованный объект, терпит неудачу.

Что мне нужно сделать, чтобы это работало?

Ответы [ 3 ]

2 голосов
/ 23 августа 2009

Класс SlaveServer является Сериализуемым. Это означает, что этот класс должен быть доступен как клиенту (фрагмент JNDI), так и серверу (MasterServer). Когда класс не может быть найден на сервере, RMI имеет возможность загрузки кода из удаленного местоположения. Однако выполнение кода, загруженного с удаленного клиента, является потенциально опасной операцией, это допустимо только в том случае, если установлен менеджер безопасности.

Вам нужно будет либо включить класс SlaveServer в приложение, содержащее MasterServer (или какой-либо путь к классу сервера), либо вам придется прекратить использование Serializable.

0 голосов
/ 25 августа 2009

Чтобы это работало, мне нужно было реализовать интерфейс ISlaveServer в качестве удаленного интерфейса RMI.

</p> <pre><code>public interface ISlaveServer extends java.rmi.Remote { ... }

и убедитесь, что класс SlaveServer был правильным RemoteObject ...

</p> <pre><code>public class SlaveServer extends java.rmi.RemoteObject implements ISlaveServer { }

Наконец я должен был убедиться, что SlaveServer был экспортирован через RMI, прежде чем его использовать ...

</p> <pre><code> static SlaveServer slaveServer = new SlaveServer(); Properties properties = new Properties(); properties.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory"); properties.put("java.naming.factory.url.pkgs", "org.jboss.naming.client"); properties.put("java.naming.provider.url", "jnp://localhost:1099"); try { Context ctx = new InitialContext(properties); IMasterServer masterServer = (IMasterServer) ctx.lookup("MasterServer"); String masterId = masterServer.getId(); masterServer.addVideoServer((ISlaveServer)UnicastRemoteObject.exportObject(slaveServer, 0)); } catch(NamingException e) { e.printStackTrace(); }

Это правильно связывается с Remote EJB и передает ссылку на мой объект SlaveServer, который EJB может использовать для обратной связи с вызывающей виртуальной машиной.

FYI SlaveServer является статическим, потому что в RMI вы несете ответственность за сохранение ссылки на реальный объект, поскольку RMI содержит только слабые ссылки. Если нет, вы получите ошибки «Объект не в таблице» из RMI.

0 голосов
/ 23 августа 2009

«Статический» был там, потому что исходный класс SlaveServer был вложенным классом.

Я переместил класс на верхний уровень (таким образом, сняв статику), и это все еще не пойдет; Я получаю то же исключение.

Мне кажется, мне нужно сделать что-то вроде «активации» CORBA для моего SlaveServer. Таким образом, сервер JBoss сможет получать заглушки для моего SlaveServer внутри Tomcat.

/ Редактировать В приложении JBoss нет реализации ISlaveServer. Я хочу, чтобы он передавал «удаленную ссылку» из приложения Tomcat в приложение JBoss, так что он все равно не должен сериализовать его (просто ссылка на него).

...