Передача по ссылке не возвращается в RMI для ArrayList

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

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

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

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

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


person jgreep    schedule 17.09.2008    source источник
comment
Здесь нет «по ссылке». Аргументы и результаты передаются по значению в RMI, если они не являются экспортируемыми удаленными объектами.   -  person user207421    schedule 02.01.2020


Ответы (4)


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

person Scott Stanchfield    schedule 17.09.2008

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

person Tom Hawtin - tackline    schedule 17.09.2008

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

person ScArcher2    schedule 17.09.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 и следует спецификации для этого интерфейса, у вас не должно возникнуть проблем.

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

person BCunningham    schedule 17.09.2008