private FileResource getNextFileResource() throws InterruptedException {
        FileResource fileResource = null;
        long start = System.currentTimeMillis();
        while (fileResource == null) {
            //check to see if thread is interrupted before polling
            if (Thread
                    .currentThread()
                    .isInterrupted()) {
                setEndedState(STATE.THREAD_INTERRUPTED);
                LOG.debug("Consumer thread was interrupted.");
                break;
            }

            synchronized (lock) {
                //need to lock here to prevent race condition with other threads setting state
                if (currentState != STATE.ACTIVELY_CONSUMING) {
                    LOG.debug("Consumer already closed because of: {}", currentState);
                    break;
                }
            }
            fileResource = fileQueue.poll(1L, TimeUnit.SECONDS);
            if (fileResource != null) {
                if (fileResource instanceof PoisonFileResource) {
                    setEndedState(STATE.SWALLOWED_POISON);
                    fileResource = null;
                }
                break;
            }
            LOG.debug("{} is waiting for file and the queue size is: {}", consumerId, fileQueue.size());

            long elapsed = System.currentTimeMillis() - start;
            if (MAX_CONSEC_WAIT_IN_MILLIS > 0 && elapsed > MAX_CONSEC_WAIT_IN_MILLIS) {
                setEndedState(STATE.EXCEEDED_MAX_CONSEC_WAIT_MILLIS);
                break;
            }
        }
        return fileResource;
    }
Use this for structured output that captures resourceId and other attributes.

@param type       entity name for exception
@param resourceId resourceId string
@param t          throwable can be null
@param attrs      (array of key0, value0, key1, value1, etc.)
tika-batch/src/main/java/org/apache/tika/batch/FileResourceConsumer.java