/** * Returns an input stream for reading the specified remote resource.<br> * * @param name the resource name * @return an input stream for reading the resource, or {@code null} if the resource could not be * found */ protected InputStream getRemoteResourceAsStream(String name) { try { log.fine("Trying to load resource " + name + " from the class provider."); ClassLoaderRequest request = new ClassLoaderRequest(name); ClassLoaderResponse response = (ClassLoaderResponse) mq.requestResponse(request, id); ClassLoaderOffer offer = response.getAcceptedOffer(); log.fine("As a response to loading " + name + " received offer " + offer); // If a remote resource was found, store it in the cache and return it if (offer != null && offer.hasFiles()) { cache.registerOffer(offer); useOffer(null, offer); String fileLocation = cache.getFileLocation(name, offer.getName()); // we could have got null because of wrong platform-dependent // separator used by user. Let's try again with fixed one. // (linux can use windows-style separators for escaping, // therefore it's not a good idea to always replace them) if (fileLocation == null) fileLocation = cache.getFileLocation( name.replace('/', File.separatorChar).replace('\\', File.separatorChar), offer.getName()); if (fileLocation != null) { return new FileInputStream(fileLocation); } else log.warning( "The received offer does not contain the file requested or the file could not be stored: cache returned NULL"); } } catch (JMSException | TimeoutException e) { throw new JCloudScaleException(e); } catch (FileNotFoundException e) { // Ignore } return null; }
/** * Loads class and all additional required information from the client. * * @param className The name of the class to load * @return The Class object of the required class. */ private Class<?> loadClassData(String className) { long start = System.nanoTime(); try { // // Creating request // ClassLoaderRequest request = createRequestFromCache(className); if (request == null) { // this class is not registered in cache log.fine( String.format( "Class %s cannot be found in cache, requesting code from the client.", className)); request = new ClassLoaderRequest(className); } else log.fine( String.format( "Class %s exists in cache in a %s offer(s). Verifying if client has the same code.", className, request.getOffers().length)); ClassLoaderResponse response = (ClassLoaderResponse) mq.requestResponse(request, id); if (response == null) { log.severe( "Client sent null response for class " + className + ". Something is wrong out there."); return null; } ClassLoaderOffer acceptedOffer = response.getAcceptedOffer(); if (acceptedOffer == null || (!acceptedOffer.hasFiles() && !acceptedOffer .hasName())) { // client does not like the stuff we sent and did not provide // anything instead. Shit, we're screwed. if (request.getOffers() == null || request.getOffers().length == 0) log.severe( String.format( "Client did not provide code for class %s and no cached version available.", className)); else log.severe( String.format( "Client did not provide code for class %s and did not selected cached version.", className)); return null; } if (!acceptedOffer .hasFiles()) // can't check whether the name is specified as it can be cache item update. { // no code from client, but offer is selected String selectedOffer = acceptedOffer.getName(); log.fine(String.format("Client selected offer %s for class %s.", selectedOffer, className)); return useOffer(className, request.getOfferByName(selectedOffer)); } else { // client provided code. log.fine( String.format( "Client provided code for class %s within %s files. saving it to cache and using it.", className, acceptedOffer.getFiles().length)); // updating the offer cache.registerOffer(acceptedOffer); // merging 2 offers together and using it.(alternative would be to create offer again from // cache, but not if NoCache is used) ClassLoaderOffer proposedOffer = request.getOfferByName(acceptedOffer.getName()); if (proposedOffer != null) updateOfferFiles(acceptedOffer, proposedOffer.getFiles()); return useOffer(className, acceptedOffer); } } catch (Exception e) { log.severe("Failed to load class " + className + ": " + e.toString()); e.printStackTrace(); return null; } finally { String msg = "REMOTE CLASS LOADER: loading of " + className + " took " + (System.nanoTime() - start) / 1000000 + "ms."; log.fine(msg); } }
/** Ensures that all additional files that this file requires are loaded. */ private void ensureAdditionalClassesLoaded(Class<?> clazz) { if (!cache.isClassLoadedFromCache(clazz)) return; if (!hasFileDependencyAnnotation(clazz)) return; // we're here if annotation is present. We have to detect if all files are loaded. // // getting items where this class is registered. // String[] items = cache.getItemNames(clazz.getName()); // finding the item that we used to instantiate this class. String usedItem = null; if (items != null) for (String item : items) if (usedOffers.contains(item)) { usedItem = item; break; } // // checking if files for this item were loaded. // ClassLoaderRequest request = null; if (usedItem != null) { String[] classesWithFiles = cache.getClassesWithFiles(usedItem); if (classesWithFiles != null && Arrays.asList(classesWithFiles).contains(clazz.getName())) return; // everything is fine, we loaded all necessary stuff. request = new ClassLoaderRequest( clazz.getName(), new ClassLoaderOffer[] {cache.createOfferByItemName(usedItem)}); } else { log.info( "Class " + clazz.getName() + " has FileDependency annotation, but we could not detect the offer that this class was taken from. Asking from the client."); request = new ClassLoaderRequest(clazz.getName()); } // files were not loaded. asking client for the data for our class. // Client will have to include files. try { ClassLoaderResponse response = (ClassLoaderResponse) mq.requestResponse(request, id); ClassLoaderOffer acceptedOffer = response.getAcceptedOffer(); // updating the offer if (acceptedOffer.hasFiles()) { cache.registerOffer(acceptedOffer); // unpacking and using it. // we don't need class, just files. but let's do the whole sequence... useOffer(null, acceptedOffer); } else log.info( "Trying to load missing dependent files of class " + clazz.getName() + " we received offer without files. Nothing to load."); } catch (JMSException | TimeoutException e) { log.severe( "Failed to load additional files for class " + clazz.getName() + " . Exception occured: " + e); return; } }