/** * 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; }
private Class<?> useOffer(String className, ClassLoaderOffer offer) { try { if (offer == null) { log.severe( "Failed to use code to resolve class " + className + " as there's no offer provided."); return null; } Class<?> requestedClass = null; // we go through all files in this offer and register them within this classloader for (ClassLoaderFile file : offer.getFiles()) { switch (file.getType()) { case CLASS: if (super.findLoadedClass(file.getName()) != null) { log.info("Attempting to load already loaded class: " + file.getName()); continue; } byte[] bytecode = file.getContent(); if (bytecode == null) // if there's no content in transmitted file, we have to get it from the // cache. bytecode = cache.getClassBytecode(file.getName(), offer.getName()); if (bytecode == null) { log.severe( "Failed to define class " + file.getName() + " from offer " + offer.getName()); continue; } Class<?> clazz = defineClass(file.getName(), bytecode, 0, bytecode.length); if (clazz.getName().equals(className)) requestedClass = clazz; break; case JAR: String path = cache.getFileLocation(file.getName(), offer.getName()); if (path == null) { log.severe( "Failed to find file " + file.getName() + " from package " + offer.getName()); continue; } try { addURL(new File(path).toURI().toURL()); } catch (MalformedURLException e) { log.severe("Exception while registering file " + path + ":" + e.toString()); continue; } break; case ROFILE: // case RWFILE: if (!cache.deployFile(file.getName(), offer.getName())) log.severe( "Failed to deploy required file " + file.getName() + ". Failed to write file to disk."); break; default: log.severe( "Unexpected type of file (" + file.getType() + ") provided in the offer. skipping."); } } if (className != null && requestedClass == null) { // this can happen as it is possible that the required class is in the jar byte[] bytecode = cache.getClassBytecode(className, offer.getName()); if (bytecode != null) requestedClass = defineClass(className, bytecode, 0, bytecode.length); } usedOffers.add(offer.getName()); // if everything is fine, we add this offer as used. return requestedClass; } catch (Throwable ex) { log.severe( "Failed to use offer " + (offer != null ? offer.getName() : "NULL offer ") + " from the cache. Removing the offer and failing..."); if (offer != null) cache.removeOfferByName(offer.getName()); throw ex; } }