Skip to main content

FileProcessor interface

DirPoll.FileProcessor gives you the File handle directly. By the time your processor is called, DirPoll has already moved the file from request/ into the run/ directory. You are responsible for reading it; DirPoll is responsible for what happens to it afterwards (archive or delete on success, bad/ on error).

Interface

public interface FileProcessor {
void process(File file) throws DirPoll.DirPollException;
}
ParameterDescription
fileThe request file, already in the run/ directory

There is no return value. If you need to write a response file, create it directly in the response/ directory (or any other directory) from within this method.

UpperCaseFileProcessor

The tutorial's UpperCaseFileProcessor reads each request file, converts its content to upper case, and prints the result:

public class UpperCaseFileProcessor implements DirPoll.FileProcessor {

@Override
public void process(File file) throws DirPoll.DirPollException {
try {
String content = Files.readString(file.toPath(), StandardCharsets.UTF_8);
System.out.println(
"Processed [" + file.getName() + "]: " + content.trim().toUpperCase()
);
} catch (IOException e) {
throw new DirPoll.DirPollException("Error reading " + file.getName(), e);
}
}
}
Writing a response from a FileProcessor

If you need to produce a response file, write it directly to the response/ directory. Use a two-step approach — write to tmp/ first, then move it atomically into response/ — to avoid the reader picking up a partially-written file:

Path tmp  = Paths.get("dirpoll/tmp",      file.getName());
Path dest = Paths.get("dirpoll/response", file.getName());
Files.write(tmp, result);
Files.move(tmp, dest, StandardCopyOption.ATOMIC_MOVE);

When to use FileProcessor vs Processor

ProcessorFileProcessor
Inputbyte[]File in run/
Responsereturned byte[]write manually
Large filesloads entire file into memorycan stream
Best forsmall, structured payloadslarge files, binary data, no response needed

Logging from a FileProcessor

DirPoll.FileProcessor has no return value, so reaching for System.out.println is tempting. It works — the redirect=stdout,stderr property in 00_logger.xml installs a LogEventOutputStream that captures stdout and re-emits each line as a jPOS log event. However, that stream batches output with a 500 ms delay before flushing, and the capture is set up during LoggerAdaptor.startService() — after all log-listeners have been registered.

The idiomatic jPOS approach is to implement SimpleLogSource and call Logger.log() directly. DirPollAdaptor detects LogSource and injects the Q2 logger automatically, so no extra wiring is needed:

public class UpperCaseFileProcessor extends SimpleLogSource
implements DirPoll.FileProcessor {

@Override
public void process(File file) throws DirPoll.DirPollException {
try {
String upper = Files.readString(file.toPath(), StandardCharsets.UTF_8)
.trim().toUpperCase();
LogEvent evt = new LogEvent(this, "upper-case-processor");
evt.addMessage("file: " + file.getName());
evt.addMessage("result: " + upper);
Logger.log(evt);
} catch (IOException e) {
throw new DirPoll.DirPollException("Error reading " + file.getName(), e);
}
}
}

This produces a properly structured log event — realm, timestamp, and message — immediately, with no batching delay.

Swapping the processor

To switch from EchoProcessor to UpperCaseFileProcessor, change the processor attribute in the deploy descriptor:

<attr name="processor">org.jpos.tutorial.UpperCaseFileProcessor</attr>

No other change is needed. DirPoll does not write to response/ when using a FileProcessor, so you can safely remove or ignore the response/ directory.