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;
}
| Parameter | Description |
|---|---|
file | The 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);
}
}
}
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
Processor | FileProcessor | |
|---|---|---|
| Input | byte[] | File in run/ |
| Response | returned byte[] | write manually |
| Large files | loads entire file into memory | can stream |
| Best for | small, structured payloads | large 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.