code: public static synchronized ExecutionSignature createSignature(
  			final Class<? extends AbstractInvokable> invokableClass, final JobID jobID) {
  
  		// First, try to load message digest algorithm, if necessary
  		if (messageDigest == null) {
  			try {
  				messageDigest = MessageDigest.getInstance(HASHINGALGORITHM);
  			} catch (NoSuchAlgorithmException e) {
  				LOG.error("Unable to load message digest algorithm " + HASHINGALGORITHM);
  				return null;
  			}
  		}
  
  		// Reset digest buffer and add the name of the invokable class to the message digest buffer
  		messageDigest.reset();
  		messageDigest.update(invokableClass.getName().getBytes());
  
  		String[] requiredJarFiles;
  		// Next, retrieve the JAR-files associated with this job
  		try {
  			requiredJarFiles = LibraryCacheManager.getRequiredJarFiles(jobID);
  		} catch (IOException ioe) {
  			// Output an error message and return
  			LOG.error("Cannot access library cache manager for job ID " + jobID);
  			return null;
  		}
  
  		// Now, sort the list of JAR-files in order to always calculate the signature in the same manner
  		Arrays.sort(requiredJarFiles);
  
  		// Finally, add the names of the JAR-files to the hash calculation
  		for (int i = 0; i < requiredJarFiles.length; i++) {
  			messageDigest.update(requiredJarFiles[i].getBytes());
  		}
  
  		return new ExecutionSignature(messageDigest.digest());
  	}
docs: Calculates the execution signature from the given class name and job ID.
  
  @param invokableClass
  the name of the class to contain the task program
  @param jobID
  the ID of the job
  @return the cryptographic signature of this vertex