/**
   * Reads required JAR files from an input stream and adds them to the library cache manager.
   *
   * @param in the data stream to read the JAR files from
   * @throws IOException thrown if an error occurs while reading the stream
   */
  private void readRequiredJarFiles(final DataInput in) throws IOException {

    // Do jar files follow;
    final int numJars = in.readInt();

    if (numJars > 0) {

      for (int i = 0; i < numJars; i++) {

        final Path p = new Path();
        p.read(in);
        this.userJars.add(p);

        // Read the size of the jar file
        final long sizeOfJar = in.readLong();

        // Add the jar to the library manager
        LibraryCacheManager.addLibrary(this.jobID, p, sizeOfJar, in);
      }
    }

    // Register this job with the library cache manager
    LibraryCacheManager.register(this.jobID, this.userJars.toArray(new Path[0]));
  }
  /**
   * Writes the JAR files of all vertices in array <code>jobVertices</code> to the specified output
   * stream.
   *
   * @param out the output stream to write the JAR files to
   * @param jobVertices array of job vertices whose required JAR file are to be written to the
   *     output stream
   * @throws IOException thrown if an error occurs while writing to the stream
   */
  private void writeRequiredJarFiles(final DataOutput out, final AbstractJobVertex[] jobVertices)
      throws IOException {

    // Now check if all the collected jar files really exist
    final FileSystem fs = FileSystem.getLocalFileSystem();

    for (int i = 0; i < this.userJars.size(); i++) {
      if (!fs.exists(this.userJars.get(i))) {
        throw new IOException("Cannot find jar file " + this.userJars.get(i));
      }
    }

    // How many jar files follow?
    out.writeInt(this.userJars.size());

    for (int i = 0; i < this.userJars.size(); i++) {

      final Path jar = this.userJars.get(i);

      // Write out the actual path
      jar.write(out);

      // Write out the length of the file
      final FileStatus file = fs.getFileStatus(jar);
      out.writeLong(file.getLen());

      // Now write the jar file
      final FSDataInputStream inStream = fs.open(this.userJars.get(i));
      final byte[] buf = new byte[BUFFERSIZE];
      int read = inStream.read(buf, 0, buf.length);
      while (read > 0) {
        out.write(buf, 0, read);
        read = inStream.read(buf, 0, buf.length);
      }
    }
  }