code: private void registerInternal(final JobID id, final String[] requiredJarFiles) throws IOException {
  
  		// Use spin lock here
  		while (this.lockMap.putIfAbsent(id, LOCK_OBJECT) != null);
  
  		try {
  			if (incrementReferenceCounter(id) > 1) {
  				return;
  			}
  
  			// Check if library manager entry for this id already exists
  			if (this.libraryManagerEntries.containsKey(id)) {
  				throw new IllegalStateException("Library cache manager already contains entry for job ID " + id);
  			}
  
  			// Check if all the required jar files exist in the cache
  			URL[] urls = null;
  			if (requiredJarFiles != null) {
  
  				urls = new URL[requiredJarFiles.length];
  
  				for (int i = 0; i < requiredJarFiles.length; i++) {
  					final Path p = contains(requiredJarFiles[i]);
  					if (p == null) {
  						throw new IOException(requiredJarFiles[i] + " does not exist in the library cache");
  					}
  
  					// Add file to the URL array
  					try {
  						urls[i] = p.toUri().toURL();
  					} catch (MalformedURLException e) {
  						throw new IOException(StringUtils.stringifyException(e));
  					}
  				}
  			}
  
  			final LibraryManagerEntry entry = new LibraryManagerEntry(id, requiredJarFiles, urls);
  
  			this.libraryManagerEntries.put(id, entry);
  
  		} finally {
  			this.lockMap.remove(id);
  		}
  	}
docs: Registers a job ID with a set of library paths that are required to run the job. For every registered
  job the library cache manager creates a class loader that is used to instantiate the vertex's environment later
  on.
  
  @param id
  the ID of the job to be registered.
  @param clientPaths
  the client path's of the required libraries
  @throws IOException
  thrown if one of the requested libraries is not in the cache