Свързано с: Предаване на отдалечени параметри в RMI
Здравейте,
Търся решение за следния проблем: Имам локални обекти (да кажем от тип MyObject), които са представени дистанционно от RemoteObject с препратка към тези обекти.
public class RemoteMyObject extends UnicastRemoteObject implements MyRemoteInterface {
MyObject refToLocale;
protected RemoteMyObject(MyObject locale) throws RemoteException {
super();
refToLocale = locale;
}
@Override // MyRemoteInterface
public void doSomething() throws RemoteException {
System.out.println("did it!");
}
public MyObject getLocale() {
return refToLocale;
}
}
Това работи според очакванията. Не искам да сериализирам MyObject
, защото има препратки към други несерилизируеми класове и файловете с класове са кодирани. Сега имам колекции от MyObject
и искам да ги манипулирам дистанционно. Така че внедрих RemoteCollection
.
public class MyRemoteCollection extends UnicastRemoteObject implements
RemoteCollection<MyRemoteInterface> {
Collection<MyObject> localeCollection;
public MyRemoteCollection(Collection<MyObject> locale) throws RemoteException {
super();
localeCollection = locale;
}
@Override
public Collection<RemoteMyObject> getItems() throws RemoteException {
ArrayList<RemoteMyObject> result = new ArrayList<RemoteMyObject>();
for (MyObject locale : localeCollection) {
result.add(new RemoteMyObject(locale));
}
return result;
}
@Override
public void delete(MyRemoteInterface obj) {
MyObject locale = ((RemoteMyObject)obj).getLocale();
localeCollection.remove(locale);
}
}
Проблемът сега е, че клиентът извиква getItems()
чрез RMI и получава колекция от отдалечени/прокси обекти. Тези обекти могат да се използват както обикновено (мога да извикам doSomething()
), но веднага щом искам един от тези обекти да бъде изтрит, имам проблем: delete()
-Методът очаква обект, който може да прехвърли към RemoteMyObject
, за да получи препратката към локала, но доставеният аргумент е просто мъниче и затова актьорският състав се проваля.
Тъй като обектът първоначално беше създаден на сървъра, въпросът ми сега е дали мога да върна локалния обект или има по-елегантно решение за решаване на проблема?
Благодаря ви, че прочетохте.
За пълнота на интерфейсите и сървъра и клиента:
public interface MyRemoteInterface extends Remote {
void doSomething() throws RemoteException;
}
public interface RemoteCollection<REM> extends Remote {
Collection< ? extends REM> getItems() throws RemoteException;
void delete(REM obj) throws RemoteException;
}
public class MainServer {
public static void main(String[] args) {
try {
Registry registry = java.rmi.registry.LocateRegistry.createRegistry(1099);
Collection<MyObject> coll = new ArrayList<>();
coll.add(new MyObject());
coll.add(new MyObject());
coll.add(new MyObject());
MyRemoteCollection remCol = new MyRemoteCollection(coll);
registry.rebind("mylist", remCol);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
public class MainClient {
public static void main(String[] args) {
try {
Registry registry = LocateRegistry.getRegistry("localhost", 1099);
RemoteCollection<MyRemoteInterface> remCol = (RemoteCollection<MyRemoteInterface>)registry.lookup("mylist");
for (MyRemoteInterface item : remCol.getItems()) {
item.doSomething();
remCol.delete(item);
}
} catch (RemoteException | NotBoundException e) {
e.printStackTrace();
}
}
}