Передача по ссылке не возвращается в RMI для ArrayList - PullRequest
0 голосов
/ 17 сентября 2008

У меня есть вызов RMI, определенный как:

public void remoteGetCustomerNameNumbers(ArrayList<String> customerNumberList, ArrayList<String> customerNameList) throws java.rmi.RemoteException;

Функция выполняет поиск в базе данных и заполняет два ArrayLists. Вызывающая функция ничего не получает. Я считаю, что это работает с типами Vector.

Нужно ли использовать Вектор или есть способ заставить это работать без двух вызовов? У меня есть другие идеи, которые я, вероятно, использовал бы, например, возвращение пары ключ / значение, но я хотел бы знать, смогу ли я заставить это работать.

Обновление:
Я бы принял все ответы, данные до сих пор, если бы мог. Я не знал стоимости сети, поэтому имеет смысл переделать функцию, чтобы она возвращала LinkedHashMap вместо двух ArrayLists.

Ответы [ 4 ]

2 голосов
/ 17 сентября 2008

Аргументы в RMI вызывают сериализацией. При десериализации на сервере создается копия списков. Если бы списки остались на стороне клиента, то количество сетевых вызовов было бы довольно высоким. Вы можете передавать удаленные объекты, но остерегайтесь последствий для производительности.

1 голос
/ 17 сентября 2008

Как уже упоминали другие, при передаче объектов в качестве параметров в метод RMI, объект сериализуется, а затем десериализуется на другом конце внутри целевого объекта, содержащего метод RMI. Это разрывает ссылку от переданных исходных объектов, поскольку теперь у вас есть два различных объекта: один в клиентском коде, вызывающем метод, и один на удаленной стороне.

В этом конкретном примере лучшим подходом будет разбить вызовы вашего метода (так как вы, кажется, делаете две вещи в одном методе: получение имен клиентов и получение номеров клиентов), и вместо этого ваши результаты скорее возвращаются вызывающей стороне. чем передать в коллекцию ... как это:

public ArrayList<String> getCustomerNames() throws java.rmi.RemoteException;

public ArrayList<String> getCustomerNumbers() throws java.rmi.RemoteException;

Поскольку и ArrayList, и String реализуют Serializable, результаты в коллекции будут сериализованы и отправлены по кабелю клиентскому коду, вызывающему метод, после чего вы можете работать с данными, как вам нужно. Если вместо этого вам нужно использовать пользовательский объект в коллекции, пока ваш класс реализует интерфейс java.io.Serializable и следует спецификации для этого интерфейса, у вас не должно возникнуть проблем.

Это приведет к двум отдельным вызовам по проводной линии, но это намного более чистое и простое взаимодействие и позволит избежать проблемы разрыва ссылок в вашем исходном примере.

1 голос
/ 17 сентября 2008

Как упоминает Том, вы можете передавать удаленные объекты. Вам нужно создать класс для хранения вашего списка, который реализует Remote. Каждый раз, когда вы передаете что-то, что реализует Remote в качестве аргумента, всякий раз, когда принимающая сторона использует это, оно поворачивается и делает удаленный вызов back вызывающей стороне для работы с этим объектом.

1 голос
/ 17 сентября 2008

Вы теряете свои ссылки, когда вы делаете удаленный вызов. Вам нужно будет возвращать списки, а не ожидать, что они будут заполнены удаленным вызовом.

...