public static RjsConnection lookup( final Registry registry, final RemoteException registryException, final RMIAddress address) throws CoreException { if (address == null) { throw new NullPointerException(); } final int[] clientVersion = AbstractRJComClient.version(); clientVersion[2] = -1; final Server server; int[] version; try { if (registryException != null) { throw registryException; } server = (Server) registry.lookup(address.getName()); version = server.getVersion(); } catch (final NotBoundException e) { throw new CoreException( new Status( IStatus.ERROR, RConsoleCorePlugin.PLUGIN_ID, ICommonStatusConstants.LAUNCHING, "The specified R engine is not in the service registry (RMI).", e)); } catch (final RemoteException e) { throw new CoreException( new Status( IStatus.ERROR, RConsoleCorePlugin.PLUGIN_ID, ICommonStatusConstants.LAUNCHING, NLS.bind( "Cannot access the host/service registry (RMI) at ''{0}''.", address.getRegistryAddress()), e)); } catch (final ClassCastException e) { throw new CoreException( new Status( IStatus.ERROR, RConsoleCorePlugin.PLUGIN_ID, ICommonStatusConstants.LAUNCHING, NLS.bind( "The specified R engine ({0}) is incompatibel to this client ({1}).", RjsUtil.getVersionString(null), RjsUtil.getVersionString(clientVersion)), e)); } if (version.length != 3 || version[0] != clientVersion[0] || version[1] != clientVersion[1]) { throw new CoreException( new Status( IStatus.ERROR, RConsoleCorePlugin.PLUGIN_ID, ICommonStatusConstants.LAUNCHING, NLS.bind( "The specified R engine ({0}) is incompatibel to this client ({1}).", RjsUtil.getVersionString(version), RjsUtil.getVersionString(clientVersion)), null)); } return new RjsConnection(address, server); }
/** * @param process the R process the controller belongs to * @param address the RMI address * @param initData the initialization data * @param embedded flag if running in embedded mode * @param startup flag to start R (otherwise connect only) * @param rArgs R arguments (required only if startup is <code>true</code>) * @param initialWD */ public RjsController( final RProcess process, final RMIAddress address, final RjsConnection connection, final Map<String, Object> initData, final boolean embedded, final boolean startup, final String[] rArgs, final Map<String, Object> rjsProperties, final IFileStore initialWD, final RWorkspaceConfig workspaceConfig, final List<TrackingConfiguration> trackingConfigurations) { super(process, initData); if (address == null || connection == null) { throw new IllegalArgumentException(); } process.registerFeatureSet(RTool.R_DATA_FEATURESET_ID); process.registerFeatureSet("de.walware.rj.services.RService"); // $NON-NLS-1$ if (!embedded) { process.registerFeatureSet(IRemoteEngineController.FEATURE_SET_ID); } fAddress = address; fRjsConnection = connection; fEmbedded = embedded; fStartup = startup; fRArgs = rArgs; fRjsProperties = (rjsProperties != null) ? rjsProperties : new HashMap<String, Object>(); fTrackingConfigurations = trackingConfigurations; fWorkspaceData = new RWorkspace( this, (embedded || address.isLocalHost()) ? null : address.getHostAddress().getHostAddress(), workspaceConfig); setWorkspaceDirL(initialWD); initRunnableAdapterL(); }
@Override protected void clear() { fRjs.setClosed(true); super.clear(); if (fEmbedded && !isDisconnected()) { try { Naming.unbind(fAddress.getAddress()); } catch (final Throwable e) { } } fRjs.disposeAllGraphics(); if (fRjsId > 0) { RjsComConfig.unregisterClientComHandler(fRjsId); fRjsId = 0; } }
/** * Requests a {@link RServi} instance from a pool. The pool must be accessible via RMI under the * given address. * * <p>The R services returned by this method are available for exclusive usage by the caller * (consumer). The consumer is responsible to return it to the pool by {@link RServi#close() * closing} the RServi. * * <p>For SSL connections, use the prefix <code>ssl:</code>. Note that SSL requires the * configuration of keystore and truststore at server and client side. * * @param address the RMI address of the pool * @param name a name which can be used to identify the client * @return a reference to the RServi instance * @throws CoreException if the operation was failed; the status of the exception contains detail * about the cause * @throws NoSuchElementException if there is currently no free RServi instance available. A later * call with the same configuration can be successfully. * @throws LoginException if the RServi request requires authentication */ public static RServi getRServi(final String address, final String name) throws CoreException, NoSuchElementException, LoginException { try { RjsComConfig.setRMIClientSocketFactory(null); RServiPool pool; try { final RMIAddress rmiAddress = new RMIAddress(address); final Registry registry = LocateRegistry.getRegistry( rmiAddress.getHost(), rmiAddress.getPortNum(), (rmiAddress.isSSL()) ? new SslRMIClientSocketFactory() : null); pool = (RServiPool) registry.lookup(rmiAddress.getName()); } catch (final MalformedURLException e) { throw new CoreException( new Status(IStatus.ERROR, RJ_SERVI_ID, 0, "Invalid address for the RServi pool.", e)); } catch (final UnknownHostException e) { throw new CoreException( new Status(IStatus.ERROR, RJ_SERVI_ID, 0, "Invalid address for the RServi pool.", e)); } catch (final NotBoundException e) { throw new CoreException( new Status( IStatus.ERROR, RJ_SERVI_ID, 0, "The address does not point to a valid RServi pool.", e)); } catch (final ClassCastException e) { throw new CoreException( new Status( IStatus.ERROR, RJ_SERVI_ID, 0, "The address does not point to a valid/compatible RServi pool.", e)); } catch (final RemoteException e) { throw new CoreException( new Status( IStatus.ERROR, RJ_SERVI_ID, 0, "Failed looking for RServi pool in the RMI registry.", e)); } try { return pool.getRServi(name, null); } catch (final RjException e) { throw new CoreException( new Status( IStatus.ERROR, RJ_SERVI_ID, 0, "Failed getting an RServi instance from the RServi pool.", e)); } catch (final RemoteException e) { throw new CoreException( new Status( IStatus.ERROR, RJ_SERVI_ID, 0, "Failed looking for RServi pool in the RMI registry.", e)); } } finally { RjsComConfig.clearRMIClientSocketFactory(); } }
@Override protected void startToolL(final IProgressMonitor monitor) throws CoreException { fRjsId = RjsComConfig.registerClientComHandler(fRjs); fRjs.initClient(getTool(), this, fRjsProperties, fRjsId); try { final Map<String, Object> data = new HashMap<String, Object>(); final IToolEventHandler loginHandler = getEventHandler(IToolEventHandler.LOGIN_REQUEST_EVENT_ID); String msg = null; boolean connected = false; while (!connected) { final Map<String, Object> initData = getInitData(); final ServerLogin login = fRjsConnection.getServer().createLogin(Server.C_CONSOLE_CONNECT); try { final Callback[] callbacks = login.getCallbacks(); if (callbacks != null) { final List<Callback> checked = new ArrayList<Callback>(); FxCallback fx = null; for (final Callback callback : callbacks) { if (callback instanceof FxCallback) { fx = (FxCallback) callback; } else { checked.add(callback); } } if (initData != null) { data.putAll(initData); } data.put( LOGIN_ADDRESS_DATA_KEY, (fx != null) ? fAddress.getHost() : fAddress.getAddress()); data.put(LOGIN_MESSAGE_DATA_KEY, msg); data.put(LOGIN_CALLBACKS_DATA_KEY, checked.toArray(new Callback[checked.size()])); if (loginHandler == null) { throw new CoreException( new Status( IStatus.ERROR, RConsoleCorePlugin.PLUGIN_ID, ICommonStatusConstants.LAUNCHING, "Login requested but not supported by this configuration.", null)); } if (!loginHandler .handle(IToolEventHandler.LOGIN_REQUEST_EVENT_ID, this, data, monitor) .isOK()) { throw new CoreException(Status.CANCEL_STATUS); } if (fx != null) { RjsUtil.handleFxCallback( RjsUtil.getSession(data, new SubProgressMonitor(monitor, 1)), fx, new SubProgressMonitor(monitor, 1)); } } msg = null; if (monitor.isCanceled()) { throw new CoreException(Status.CANCEL_STATUS); } final Map<String, Object> args = new HashMap<String, Object>(); args.putAll(fRjsProperties); ConsoleEngine rjServer; if (fStartup) { args.put("args", fRArgs); // $NON-NLS-1$ rjServer = (ConsoleEngine) fRjsConnection .getServer() .execute(Server.C_CONSOLE_START, args, login.createAnswer()); } else { rjServer = (ConsoleEngine) fRjsConnection .getServer() .execute(Server.C_CONSOLE_CONNECT, args, login.createAnswer()); } fRjs.setServer(rjServer, 0); connected = true; if (callbacks != null) { loginHandler.handle(IToolEventHandler.LOGIN_OK_EVENT_ID, this, data, monitor); if (initData != null) { initData.put(LOGIN_USERNAME_DATA_KEY, data.get(LOGIN_USERNAME_DATA_KEY)); } } } catch (final LoginException e) { msg = e.getLocalizedMessage(); } finally { if (login != null) { login.clearData(); } } } final ServerInfo info = fRjsConnection.getServer().getInfo(); if (fWorkspaceData.isRemote()) { try { final String wd = FileUtil.toString(fWorkspaceData.toFileStore(info.getDirectory())); if (wd != null) { setStartupWD(wd); } } catch (final CoreException e) { } } else { setStartupWD(info.getDirectory()); } final long timestamp = info.getTimestamp(); if (timestamp != 0) { setStartupTimestamp(timestamp); } final List<IStatus> warnings = new ArrayList<IStatus>(); initTracks(info.getDirectory(), monitor, warnings); if (fStartup && !fStartupsRunnables.isEmpty()) { fQueue.add(fStartupsRunnables.toArray(new IToolRunnable[fStartupsRunnables.size()])); fStartupsRunnables.clear(); } if (!fStartup) { handleStatus( new Status( IStatus.INFO, RConsoleCorePlugin.PLUGIN_ID, addTimestampToMessage( RNicoMessages.R_Info_Reconnected_message, fProcess.getConnectionTimestamp())), monitor); } // fRjs.runMainLoop(null, null, monitor); must not wait at server side fRjs.activateConsole(); scheduleControllerRunnable( new ControllerSystemRunnable( "r/rj/start2", "Finish Initialization / Read Output") { // $NON-NLS-1$ @Override public void run(final IToolService s, final IProgressMonitor monitor) throws CoreException { if (!fRjs.isConsoleReady()) { // R is still working fRjs.runMainLoop(null, null, monitor); } for (final IStatus status : warnings) { handleStatus(status, monitor); } } }); } catch (final RemoteException e) { throw new CoreException( new Status( IStatus.ERROR, RConsoleCorePlugin.PLUGIN_ID, ICommonStatusConstants.LAUNCHING, "The R engine could not be started.", e)); } catch (final RjException e) { throw new CoreException( new Status( IStatus.ERROR, RConsoleCorePlugin.PLUGIN_ID, ICommonStatusConstants.LAUNCHING, "An error occured when creating login data.", e)); } }