Java Code Examples for java.io.IOException#addSuppressed()

The following examples show how to use java.io.IOException#addSuppressed() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: DirArchive.java    From openjdk-jdk9 with GNU General Public License v2.0 6 votes vote down vote up
@Override
public void close() throws IOException {
    IOException e = null;
    for (InputStream stream : open) {
        try {
            stream.close();
        } catch (IOException ex) {
            if (e == null) {
                e = ex;
            } else {
                e.addSuppressed(ex);
            }
        }
    }
    if (e != null) {
        throw e;
    }
}
 
Example 2
Source File: SmbTransportImpl.java    From jcifs with GNU Lesser General Public License v2.1 6 votes vote down vote up
protected void doSend0 ( Request request ) throws IOException {
    try {
        doSend(request);
    }
    catch ( IOException ioe ) {
        log.warn("send failed", ioe);
        try {
            disconnect(true);
        }
        catch ( IOException ioe2 ) {
            ioe.addSuppressed(ioe2);
            log.error("disconnect failed", ioe2);
        }
        throw ioe;
    }
}
 
Example 3
Source File: SmbTransportImpl.java    From jcifs-ng with GNU Lesser General Public License v2.1 6 votes vote down vote up
protected void doSend0 ( Request request ) throws IOException {
    try {
        doSend(request);
    }
    catch ( IOException ioe ) {
        log.warn("send failed", ioe);
        try {
            disconnect(true);
        }
        catch ( IOException ioe2 ) {
            ioe.addSuppressed(ioe2);
            log.error("disconnect failed", ioe2);
        }
        throw ioe;
    }
}
 
Example 4
Source File: FsBlobContainer.java    From crate with Apache License 2.0 6 votes vote down vote up
@Override
public void writeBlobAtomic(final String blobName, final InputStream inputStream, final long blobSize, boolean failIfAlreadyExists)
    throws IOException {
    final String tempBlob = tempBlobName(blobName);
    final Path tempBlobPath = path.resolve(tempBlob);
    try {
        try (OutputStream outputStream = Files.newOutputStream(tempBlobPath, StandardOpenOption.CREATE_NEW)) {
            Streams.copy(inputStream, outputStream);
        }
        IOUtils.fsync(tempBlobPath, false);
        moveBlobAtomic(tempBlob, blobName, failIfAlreadyExists);
    } catch (IOException ex) {
        try {
            deleteBlobIgnoringIfNotExists(tempBlob);
        } catch (IOException e) {
            ex.addSuppressed(e);
        }
        throw ex;
    } finally {
        IOUtils.fsync(path, true);
    }
}
 
Example 5
Source File: FileUtils.java    From incubator-pinot with Apache License 2.0 6 votes vote down vote up
/**
 * Close a collection of {@link Closeable} resources
 * This is a utility method to help release multiple {@link Closeable}
 * resources in a safe manner without leaking.
 * As an example if we have a list of Closeable resources,
 * then the following code is prone to leaking 1 or more
 * subsequent resources if an exception is thrown while
 * closing one of them.
 *
 * for (closeable_resource : resources) {
 *   closeable_resource.close()
 * }
 *
 * The helper methods provided here do this safely
 * while keeping track of exception(s) raised during
 * close() of each resource and still continuing to close
 * subsequent resources.
 * @param closeables collection of resources to close
 * @throws IOException
 */
public static void close(Iterable<? extends Closeable> closeables)
    throws IOException {
  IOException topLevelException = null;

  for (Closeable closeable : closeables) {
    try {
      if (closeable != null) {
        closeable.close();
      }
    } catch (IOException e) {
      if (topLevelException == null) {
        topLevelException = e;
      } else if (e != topLevelException) {
        topLevelException.addSuppressed(e);
      }
    }
  }

  if (topLevelException != null) {
    throw topLevelException;
  }
}
 
Example 6
Source File: BigQueryHelper.java    From hadoop-connectors with Apache License 2.0 5 votes vote down vote up
/**
 * Tries to run jobs().insert(...) with the provided {@code projectId} and {@code job}, which
 * returns a {@code Job} under normal operation, which is then returned from this method. In case
 * of an exception being thrown, if the cause was "409 conflict", then we issue a separate
 * "jobs().get(...)" request and return the results of that fetch instead. Other exceptions
 * propagate out as normal.
 */
public Job insertJobOrFetchDuplicate(String projectId, Job job) throws IOException {
  checkArgument(
      job.getJobReference() != null && job.getJobReference().getJobId() != null,
      "Require non-null JobReference and JobId inside; getJobReference() == '%s'",
      job.getJobReference());
  Job response;
  try {
    response = service.jobs().insert(projectId, job).execute();
    logger.atFine().log("Successfully inserted job '%s'. Response: '%s'", job, response);
  } catch (IOException insertJobException) {
    if (errorExtractor.itemAlreadyExists(insertJobException)) {
      logger.atInfo().withCause(insertJobException).log(
          "Fetching existing job after catching exception for duplicate jobId '%s'",
          job.getJobReference().getJobId());
      try {
        response = service.jobs().get(projectId, job.getJobReference().getJobId()).execute();
      } catch (IOException getJobException) {
        getJobException.addSuppressed(insertJobException);
        throw new IOException(
            String.format("Failed to get duplicate job '%s'", job), getJobException);
      }
    } else {
      throw new IOException(
          String.format("Unhandled exception trying to insert job '%s'", job),
          insertJobException);
    }
  }
  checkJobIdEquality(job, response);
  return response;
}
 
Example 7
Source File: TestHelper.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Attempt to create a file at the given location. If an IOException
 * occurs then back off for a moment and try again. When a number of
 * attempts fail, give up and throw an exception.
 */
void createAFile(File aFile, List<String> contents) throws IOException {
    IOException cause = null;
    for (int attempts = 0; attempts < 10; attempts++) {
        try {
            Files.write(aFile.getAbsoluteFile().toPath(), contents,
                Charset.defaultCharset(), CREATE, TRUNCATE_EXISTING, WRITE);
            if (cause != null) {
                /*
                 * report attempts and errors that were encountered
                 * for diagnostic purposes
                 */
                System.err.println("Created batch file " +
                                    aFile + " in " + (attempts + 1) +
                                    " attempts");
                System.err.println("Errors encountered: " + cause);
                cause.printStackTrace();
            }
            return;
        } catch (IOException ioe) {
            if (cause != null) {
                // chain the exceptions so they all get reported for diagnostics
                cause.addSuppressed(ioe);
            } else {
                cause = ioe;
            }
        }

        try {
            Thread.sleep(500);
        } catch (InterruptedException ie) {
            if (cause != null) {
                // cause should alway be non-null here
                ie.addSuppressed(cause);
            }
            throw new RuntimeException("Interrupted while creating batch file", ie);
        }
    }
    throw new RuntimeException("Unable to create batch file", cause);
}
 
Example 8
Source File: TestHelper.java    From TencentKona-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Attempt to create a file at the given location. If an IOException
 * occurs then back off for a moment and try again. When a number of
 * attempts fail, give up and throw an exception.
 */
void createAFile(File aFile, List<String> contents) throws IOException {
    IOException cause = null;
    for (int attempts = 0; attempts < 10; attempts++) {
        try {
            Files.write(aFile.getAbsoluteFile().toPath(), contents,
                Charset.defaultCharset(), CREATE, TRUNCATE_EXISTING, WRITE);
            if (cause != null) {
                /*
                 * report attempts and errors that were encountered
                 * for diagnostic purposes
                 */
                System.err.println("Created batch file " +
                                    aFile + " in " + (attempts + 1) +
                                    " attempts");
                System.err.println("Errors encountered: " + cause);
                cause.printStackTrace();
            }
            return;
        } catch (IOException ioe) {
            if (cause != null) {
                // chain the exceptions so they all get reported for diagnostics
                cause.addSuppressed(ioe);
            } else {
                cause = ioe;
            }
        }

        try {
            Thread.sleep(500);
        } catch (InterruptedException ie) {
            if (cause != null) {
                // cause should alway be non-null here
                ie.addSuppressed(cause);
            }
            throw new RuntimeException("Interrupted while creating batch file", ie);
        }
    }
    throw new RuntimeException("Unable to create batch file", cause);
}
 
Example 9
Source File: FileUtils.java    From jdk8u-jdk with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Deletes a directory and its subdirectories, retrying if necessary.
 *
 * @param dir  the directory to delete
 *
 * @throws  IOException
 *          If an I/O error occurs. Any such exceptions are caught
 *          internally. If only one is caught, then it is re-thrown.
 *          If more than one exception is caught, then the second and
 *          following exceptions are added as suppressed exceptions of the
 *          first one caught, which is then re-thrown.
 */
public static void deleteFileTreeWithRetry(Path dir)
     throws IOException
{
    IOException ioe = null;
    final List<IOException> excs = deleteFileTreeUnchecked(dir);
    if (!excs.isEmpty()) {
        ioe = excs.remove(0);
        for (IOException x : excs)
            ioe.addSuppressed(x);
    }
    if (ioe != null)
        throw ioe;
}
 
Example 10
Source File: FileUtils.java    From TencentKona-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Deletes a directory and its subdirectories, retrying if necessary.
 *
 * @param dir  the directory to delete
 *
 * @throws  IOException
 *          If an I/O error occurs. Any such exceptions are caught
 *          internally. If only one is caught, then it is re-thrown.
 *          If more than one exception is caught, then the second and
 *          following exceptions are added as suppressed exceptions of the
 *          first one caught, which is then re-thrown.
 */
public static void deleteFileTreeWithRetry(Path dir) throws IOException {
    IOException ioe = null;
    final List<IOException> excs = deleteFileTreeUnchecked(dir);
    if (!excs.isEmpty()) {
        ioe = excs.remove(0);
        for (IOException x : excs) {
            ioe.addSuppressed(x);
        }
    }
    if (ioe != null) {
        throw ioe;
    }
}
 
Example 11
Source File: URLClassLoader.java    From jdk8u60 with GNU General Public License v2.0 5 votes vote down vote up
/**
* Closes this URLClassLoader, so that it can no longer be used to load
* new classes or resources that are defined by this loader.
* Classes and resources defined by any of this loader's parents in the
* delegation hierarchy are still accessible. Also, any classes or resources
* that are already loaded, are still accessible.
* <p>
* In the case of jar: and file: URLs, it also closes any files
* that were opened by it. If another thread is loading a
* class when the {@code close} method is invoked, then the result of
* that load is undefined.
* <p>
* The method makes a best effort attempt to close all opened files,
* by catching {@link IOException}s internally. Unchecked exceptions
* and errors are not caught. Calling close on an already closed
* loader has no effect.
* <p>
* @exception IOException if closing any file opened by this class loader
* resulted in an IOException. Any such exceptions are caught internally.
* If only one is caught, then it is re-thrown. If more than one exception
* is caught, then the second and following exceptions are added
* as suppressed exceptions of the first one caught, which is then re-thrown.
*
* @exception SecurityException if a security manager is set, and it denies
*   {@link RuntimePermission}{@code ("closeClassLoader")}
*
* @since 1.7
*/
public void close() throws IOException {
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkPermission(new RuntimePermission("closeClassLoader"));
    }
    List<IOException> errors = ucp.closeLoaders();

    // now close any remaining streams.

    synchronized (closeables) {
        Set<Closeable> keys = closeables.keySet();
        for (Closeable c : keys) {
            try {
                c.close();
            } catch (IOException ioex) {
                errors.add(ioex);
            }
        }
        closeables.clear();
    }

    if (errors.isEmpty()) {
        return;
    }

    IOException firstex = errors.remove(0);

    // Suppress any remaining exceptions

    for (IOException error: errors) {
        firstex.addSuppressed(error);
    }
    throw firstex;
}
 
Example 12
Source File: URLClassLoader.java    From jdk8u-jdk with GNU General Public License v2.0 5 votes vote down vote up
/**
* Closes this URLClassLoader, so that it can no longer be used to load
* new classes or resources that are defined by this loader.
* Classes and resources defined by any of this loader's parents in the
* delegation hierarchy are still accessible. Also, any classes or resources
* that are already loaded, are still accessible.
* <p>
* In the case of jar: and file: URLs, it also closes any files
* that were opened by it. If another thread is loading a
* class when the {@code close} method is invoked, then the result of
* that load is undefined.
* <p>
* The method makes a best effort attempt to close all opened files,
* by catching {@link IOException}s internally. Unchecked exceptions
* and errors are not caught. Calling close on an already closed
* loader has no effect.
* <p>
* @exception IOException if closing any file opened by this class loader
* resulted in an IOException. Any such exceptions are caught internally.
* If only one is caught, then it is re-thrown. If more than one exception
* is caught, then the second and following exceptions are added
* as suppressed exceptions of the first one caught, which is then re-thrown.
*
* @exception SecurityException if a security manager is set, and it denies
*   {@link RuntimePermission}{@code ("closeClassLoader")}
*
* @since 1.7
*/
public void close() throws IOException {
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkPermission(new RuntimePermission("closeClassLoader"));
    }
    List<IOException> errors = ucp.closeLoaders();

    // now close any remaining streams.

    synchronized (closeables) {
        Set<Closeable> keys = closeables.keySet();
        for (Closeable c : keys) {
            try {
                c.close();
            } catch (IOException ioex) {
                errors.add(ioex);
            }
        }
        closeables.clear();
    }

    if (errors.isEmpty()) {
        return;
    }

    IOException firstex = errors.remove(0);

    // Suppress any remaining exceptions

    for (IOException error: errors) {
        firstex.addSuppressed(error);
    }
    throw firstex;
}
 
Example 13
Source File: URLClassLoader.java    From openjdk-jdk9 with GNU General Public License v2.0 5 votes vote down vote up
/**
* Closes this URLClassLoader, so that it can no longer be used to load
* new classes or resources that are defined by this loader.
* Classes and resources defined by any of this loader's parents in the
* delegation hierarchy are still accessible. Also, any classes or resources
* that are already loaded, are still accessible.
* <p>
* In the case of jar: and file: URLs, it also closes any files
* that were opened by it. If another thread is loading a
* class when the {@code close} method is invoked, then the result of
* that load is undefined.
* <p>
* The method makes a best effort attempt to close all opened files,
* by catching {@link IOException}s internally. Unchecked exceptions
* and errors are not caught. Calling close on an already closed
* loader has no effect.
*
* @exception IOException if closing any file opened by this class loader
* resulted in an IOException. Any such exceptions are caught internally.
* If only one is caught, then it is re-thrown. If more than one exception
* is caught, then the second and following exceptions are added
* as suppressed exceptions of the first one caught, which is then re-thrown.
*
* @exception SecurityException if a security manager is set, and it denies
*   {@link RuntimePermission}{@code ("closeClassLoader")}
*
* @since 1.7
*/
public void close() throws IOException {
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkPermission(new RuntimePermission("closeClassLoader"));
    }
    List<IOException> errors = ucp.closeLoaders();

    // now close any remaining streams.

    synchronized (closeables) {
        Set<Closeable> keys = closeables.keySet();
        for (Closeable c : keys) {
            try {
                c.close();
            } catch (IOException ioex) {
                errors.add(ioex);
            }
        }
        closeables.clear();
    }

    if (errors.isEmpty()) {
        return;
    }

    IOException firstex = errors.remove(0);

    // Suppress any remaining exceptions

    for (IOException error: errors) {
        firstex.addSuppressed(error);
    }
    throw firstex;
}
 
Example 14
Source File: BigtableIO.java    From beam with Apache License 2.0 5 votes vote down vote up
/** If any write has asynchronously failed, fail the bundle with a useful error. */
private void checkForFailures() throws IOException {
  // Note that this function is never called by multiple threads and is the only place that
  // we remove from failures, so this code is safe.
  if (failures.isEmpty()) {
    return;
  }

  StringBuilder logEntry = new StringBuilder();
  int i = 0;
  List<BigtableWriteException> suppressed = Lists.newArrayList();
  for (; i < 10 && !failures.isEmpty(); ++i) {
    BigtableWriteException exc = failures.remove();
    logEntry.append("\n").append(exc.getMessage());
    if (exc.getCause() != null) {
      logEntry.append(": ").append(exc.getCause().getMessage());
    }
    suppressed.add(exc);
  }
  String message =
      String.format(
          "At least %d errors occurred writing to Bigtable. First %d errors: %s",
          i + failures.size(), i, logEntry.toString());
  LOG.error(message);
  IOException exception = new IOException(message);
  for (BigtableWriteException e : suppressed) {
    exception.addSuppressed(e);
  }
  throw exception;
}
 
Example 15
Source File: FileTreeWalker.java    From Java8CN with Apache License 2.0 4 votes vote down vote up
/**
 * Returns the next Event or {@code null} if there are no more events or
 * the walker is closed.
 */
Event next() {
    DirectoryNode top = stack.peek();
    if (top == null)
        return null;      // stack is empty, we are done

    // continue iteration of the directory at the top of the stack
    Event ev;
    do {
        Path entry = null;
        IOException ioe = null;

        // get next entry in the directory
        if (!top.skipped()) {
            Iterator<Path> iterator = top.iterator();
            try {
                if (iterator.hasNext()) {
                    entry = iterator.next();
                }
            } catch (DirectoryIteratorException x) {
                ioe = x.getCause();
            }
        }

        // no next entry so close and pop directory, creating corresponding event
        if (entry == null) {
            try {
                top.stream().close();
            } catch (IOException e) {
                if (ioe != null) {
                    ioe = e;
                } else {
                    ioe.addSuppressed(e);
                }
            }
            stack.pop();
            return new Event(EventType.END_DIRECTORY, top.directory(), ioe);
        }

        // visit the entry
        ev = visit(entry,
                   true,   // ignoreSecurityException
                   true);  // canUseCached

    } while (ev == null);

    return ev;
}
 
Example 16
Source File: ZipFileSystem.java    From jdk8u_jdk with GNU General Public License v2.0 4 votes vote down vote up
@Override
public void close() throws IOException {
    beginWrite();
    try {
        if (!isOpen)
            return;
        isOpen = false;             // set closed
    } finally {
        endWrite();
    }
    if (!streams.isEmpty()) {       // unlock and close all remaining streams
        Set<InputStream> copy = new HashSet<>(streams);
        for (InputStream is: copy)
            is.close();
    }
    beginWrite();                   // lock and sync
    try {
        sync();
        ch.close();                 // close the ch just in case no update
    } finally {                     // and sync dose not close the ch
        endWrite();
    }

    synchronized (inflaters) {
        for (Inflater inf : inflaters)
            inf.end();
    }
    synchronized (deflaters) {
        for (Deflater def : deflaters)
            def.end();
    }

    beginWrite();                // lock and sync
    try {
        // Clear the map so that its keys & values can be garbage collected
        inodes = null;
    } finally {
        endWrite();
    }

    IOException ioe = null;
    synchronized (tmppaths) {
        for (Path p: tmppaths) {
            try {
                Files.deleteIfExists(p);
            } catch (IOException x) {
                if (ioe == null)
                    ioe = x;
                else
                    ioe.addSuppressed(x);
            }
        }
    }
    provider.removeFileSystem(zfpath, this);
    if (ioe != null)
       throw ioe;
}
 
Example 17
Source File: FileTreeWalker.java    From jdk1.8-source-analysis with Apache License 2.0 4 votes vote down vote up
/**
 * Returns the next Event or {@code null} if there are no more events or
 * the walker is closed.
 */
Event next() {
    DirectoryNode top = stack.peek();
    if (top == null)
        return null;      // stack is empty, we are done

    // continue iteration of the directory at the top of the stack
    Event ev;
    do {
        Path entry = null;
        IOException ioe = null;

        // get next entry in the directory
        if (!top.skipped()) {
            Iterator<Path> iterator = top.iterator();
            try {
                if (iterator.hasNext()) {
                    entry = iterator.next();
                }
            } catch (DirectoryIteratorException x) {
                ioe = x.getCause();
            }
        }

        // no next entry so close and pop directory, creating corresponding event
        if (entry == null) {
            try {
                top.stream().close();
            } catch (IOException e) {
                if (ioe != null) {
                    ioe = e;
                } else {
                    ioe.addSuppressed(e);
                }
            }
            stack.pop();
            return new Event(EventType.END_DIRECTORY, top.directory(), ioe);
        }

        // visit the entry
        ev = visit(entry,
                   true,   // ignoreSecurityException
                   true);  // canUseCached

    } while (ev == null);

    return ev;
}
 
Example 18
Source File: ZipFileSystem.java    From openjdk-8 with GNU General Public License v2.0 4 votes vote down vote up
@Override
public void close() throws IOException {
    beginWrite();
    try {
        if (!isOpen)
            return;
        isOpen = false;             // set closed
    } finally {
        endWrite();
    }
    if (!streams.isEmpty()) {       // unlock and close all remaining streams
        Set<InputStream> copy = new HashSet<>(streams);
        for (InputStream is: copy)
            is.close();
    }
    beginWrite();                   // lock and sync
    try {
        sync();
        ch.close();                 // close the ch just in case no update
    } finally {                     // and sync dose not close the ch
        endWrite();
    }

    synchronized (inflaters) {
        for (Inflater inf : inflaters)
            inf.end();
    }
    synchronized (deflaters) {
        for (Deflater def : deflaters)
            def.end();
    }

    IOException ioe = null;
    synchronized (tmppaths) {
        for (Path p: tmppaths) {
            try {
                Files.deleteIfExists(p);
            } catch (IOException x) {
                if (ioe == null)
                    ioe = x;
                else
                    ioe.addSuppressed(x);
            }
        }
    }
    provider.removeFileSystem(zfpath, this);
    if (ioe != null)
       throw ioe;
}
 
Example 19
Source File: MinimalLockingWriteAheadLog.java    From localization_nifi with Apache License 2.0 4 votes vote down vote up
/**
 * Closes resources pointing to the current journal and begins writing
 * to a new one
 *
 * @throws IOException if failure to rollover
 */
public OutputStream rollover() throws IOException {
    // Note that here we are closing fileOut and NOT dataOut. See the note in the close()
    // method to understand the logic behind this.
    final OutputStream oldOutputStream = fileOut;
    dataOut = null;
    fileOut = null;

    this.serde = serdeFactory.createSerDe(null);
    final Path editPath = getNewEditPath();
    final FileOutputStream fos = new FileOutputStream(editPath.toFile());
    try {
        final DataOutputStream outStream = new DataOutputStream(new BufferedOutputStream(fos));
        outStream.writeUTF(MinimalLockingWriteAheadLog.class.getName());
        outStream.writeInt(writeAheadLogVersion);
        outStream.writeUTF(serde.getClass().getName());
        outStream.writeInt(serde.getVersion());
        serde.writeHeader(outStream);

        outStream.flush();
        dataOut = outStream;
        fileOut = fos;
    } catch (final IOException ioe) {
        try {
            oldOutputStream.close();
        } catch (final IOException ioe2) {
            ioe.addSuppressed(ioe2);
        }

        logger.error("Failed to create new journal for {} due to {}", new Object[] {this, ioe.toString()}, ioe);
        try {
            fos.close();
        } catch (final IOException innerIOE) {
        }

        dataOut = null;
        fileOut = null;
        blackList();

        throw ioe;
    }

    currentJournalFilename = editPath.toFile().getName();

    blackListed = false;
    return oldOutputStream;
}
 
Example 20
Source File: FileTreeWalker.java    From openjdk-jdk8u with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Returns the next Event or {@code null} if there are no more events or
 * the walker is closed.
 */
Event next() {
    DirectoryNode top = stack.peek();
    if (top == null)
        return null;      // stack is empty, we are done

    // continue iteration of the directory at the top of the stack
    Event ev;
    do {
        Path entry = null;
        IOException ioe = null;

        // get next entry in the directory
        if (!top.skipped()) {
            Iterator<Path> iterator = top.iterator();
            try {
                if (iterator.hasNext()) {
                    entry = iterator.next();
                }
            } catch (DirectoryIteratorException x) {
                ioe = x.getCause();
            }
        }

        // no next entry so close and pop directory, creating corresponding event
        if (entry == null) {
            try {
                top.stream().close();
            } catch (IOException e) {
                if (ioe != null) {
                    ioe = e;
                } else {
                    ioe.addSuppressed(e);
                }
            }
            stack.pop();
            return new Event(EventType.END_DIRECTORY, top.directory(), ioe);
        }

        // visit the entry
        ev = visit(entry,
                   true,   // ignoreSecurityException
                   true);  // canUseCached

    } while (ev == null);

    return ev;
}