/** * Splits a classpath into elements using the <code>path.separator</code> system property. * * @param elements the <code>Vector</code> to which to add the classpath elements * @param classpath the classpath to split */ private static void splitClassPath(final Vector elements, final String classpath) { String separator = System.getProperty("path.separator"); if (separator == null) { // defaults to ';' separator = ";"; Logging.report( Logging.ERROR, LogChannels.LC_AMS, "No \"path.separator\" defined! Using \"" + separator + "\"!"); } int index = classpath.indexOf(separator); int offset = 0; while (index != -1) { addClassPathElement(elements, classpath, offset, index); offset = index + separator.length(); index = classpath.indexOf(separator, offset); } addClassPathElement(elements, classpath, offset, classpath.length()); }
/** * Starts a MIDlet in a new Isolate. Check that the MIDlet is is not realy running and is not * already being started. If so, return immediately. * * @param midletSuiteStorage midletSuiteStorage for obtaining a classpath * @param externalAppId ID of MIDlet to invoke, given by an external application manager * @param id ID of an installed suite * @param midlet class name of MIDlet to invoke * @param displayName name to display to the user * @param arg0 if not null, this parameter will be available to the MIDlet as application property * arg-0 * @param arg1 if not null, this parameter will be available to the MIDlet as application property * arg-1 * @param arg2 if not null, this parameter will be available to the MIDlet as application property * arg-2 * @param memoryReserved the minimum amount of memory guaranteed to be available to the isolate at * any time; < 0 if not used * @param memoryTotal the total amount of memory that the isolate can reserve; < 0 if not used * @param priority priority to set for the new isolate; <= 0 if not used * @param profileName name of the profile to set for the new isolate; null if not used * @param debugMode debug option for the new isolate, one of: MIDP_NO_DEBUG, MIDP_DEBUG_SUSPEND, * MIDP_DEBUG_NO_SUSPEND * @return Isolate that the MIDlet suite was started in; <code>null</code> if the MIDlet is * already running */ private static Isolate startMidletCommon( MIDletSuiteStorage midletSuiteStorage, int externalAppId, int id, String midlet, String displayName, String arg0, String arg1, String arg2, int memoryReserved, int memoryTotal, int priority, String profileName, int debugMode) { Isolate isolate; String[] args = { Integer.toString(id), midlet, displayName, arg0, arg1, arg2, Integer.toString(externalAppId), String.valueOf(debugMode) }; String[] classpath = midletSuiteStorage.getMidletSuiteClassPath(id); if (classpath[0] == null) { if (id == MIDletSuite.INTERNAL_SUITE_ID) { /* * Avoid a null pointer exception, rommized midlets don't need * a classpath. */ classpath[0] = ""; } else { throw new IllegalArgumentException("Suite " + id + " not found"); } } Vector cpExtElements = new Vector(); String isolateClassPath = System.getProperty("classpathext"); if (isolateClassPath != null) { splitClassPath(cpExtElements, isolateClassPath); } /* * Include paths to dynamic components belonging to this suite * and to the "internal" suite (actually, to AMS) into class * path for the new Isolate. */ DynamicComponentStorage componentStorage = DynamicComponentStorage.getComponentStorage(); ComponentInfo[] ci = componentStorage.getListOfSuiteComponents(id); ComponentInfo[] ciAms = componentStorage.getListOfSuiteComponents(MIDletSuite.INTERNAL_SUITE_ID); int numOfComponents = 0; // calculate the number of the components to be added to the class path if (ci != null) { numOfComponents += ci.length; } if (ciAms != null) { numOfComponents += ciAms.length; } if (numOfComponents > 0) { Vector ciVector = new Vector(numOfComponents); // add the suite's own components if (ci != null) { for (int i = 0; i < ci.length; i++) { ciVector.addElement(ci[i]); } } // add the shared (belonging to AMS) components if (ciAms != null) { for (int i = 0; i < ciAms.length; i++) { ciVector.addElement(ciAms[i]); } } /* * IMPL_NOTE: currently is assumed that each component may have * not more than 1 entry in class path. * Later it will be possible to have 2: 1 for MONET. * + 1 is for System.getProperty("classpathext"). */ int n = 0; try { for (int i = 0; i < ciVector.size(); i++) { final ComponentInfo nextComponent = ((ComponentInfo) ciVector.elementAt(i)); final String[] componentPath = componentStorage.getComponentClassPath(nextComponent.getComponentId()); if (componentPath != null) { for (int j = 0; j < componentPath.length; j++) { cpExtElements.addElement(componentPath[j]); ++n; } } } } catch (Exception e) { /* * if something is wrong with a dynamic component, just * don't use the components, this error is not fatal */ cpExtElements.setSize(cpExtElements.size() - n); if (Logging.REPORT_LEVEL <= Logging.ERROR) { e.printStackTrace(); Logging.report( Logging.ERROR, LogChannels.LC_AMS, "Cannot use a dynamic component when starting '" + midlet + "' from the suite with id = " + id); } } } try { StartMIDletMonitor app = StartMIDletMonitor.okToStart(id, midlet); if (app == null) { // Isolate is already running; don't start it again return null; } final String[] classpathext = new String[cpExtElements.size()]; cpExtElements.copyInto(classpathext); isolate = new Isolate( "com.sun.midp.main.AppIsolateMIDletSuiteLoader", args, classpath, classpathext); app.setIsolate(isolate); } catch (Throwable t) { t.printStackTrace(); throw new RuntimeException("Can't create Isolate****"); } try { int reserved, limit; if (memoryReserved >= 0) { reserved = memoryReserved; } else { reserved = Constants.SUITE_MEMORY_RESERVED * 1024; } if (memoryTotal > 0) { limit = memoryTotal; } else { limit = Constants.SUITE_MEMORY_LIMIT; if (limit < 0) { limit = isolate.totalMemory(); } else { limit = limit * 1024; } int heapSize = getMidletHeapSize(id, midlet); if ((heapSize > 0) && (heapSize < limit)) { limit = heapSize; } } isolate.setMemoryQuota(reserved, limit); if (priority >= Isolate.MIN_PRIORITY) { isolate.setPriority(priority); } if (profileName != null) { IsolateUtil.setProfile(isolate, profileName); } isolate.setDebug(debugMode); isolate.setAPIAccess(true); isolate.start(); // Ability to launch midlet implies right to use Service API // for negotiations with isolate being run Link[] isolateLinks = SystemServiceLinkPortal.establishLinksFor(isolate, getTrustedToken()); LinkPortal.setLinks(isolate, isolateLinks); } catch (Throwable t) { int errorCode; String msg; if (Logging.REPORT_LEVEL <= Logging.WARNING) { t.printStackTrace(); } if (t instanceof IsolateStartupException) { /* * An error occured in the * initialization or configuration of the new isolate * before any application code is invoked, or if this * Isolate was already started or is terminated. */ errorCode = Constants.MIDLET_ISOLATE_CONSTRUCTOR_FAILED; msg = "Can't start Application."; } else if (t instanceof IsolateResourceError) { /* The system has exceeded the maximum Isolate count. */ errorCode = Constants.MIDLET_ISOLATE_RESOURCE_LIMIT; msg = "No more concurrent applications allowed."; } else if (t instanceof IllegalArgumentException) { /* Requested profile doesn't exist. */ errorCode = Constants.MIDLET_ISOLATE_CONSTRUCTOR_FAILED; msg = "Invalid profile name: " + profileName; } else if (t instanceof OutOfMemoryError) { /* The reserved memory cannot be allocated */ errorCode = Constants.MIDLET_OUT_OF_MEM_ERROR; msg = "Not enough memory to run the application."; } else { errorCode = Constants.MIDLET_ISOLATE_CONSTRUCTOR_FAILED; msg = t.toString(); } midletControllerEventProducer.sendMIDletStartErrorEvent( id, midlet, externalAppId, errorCode, msg); throw new RuntimeException(msg); } return isolate; }