If the reader is supported by the Linux kernel (as a human input device, HID), it should show up as an input event device. For each event device,
/dev/input/eventX, you can read the vendor ID from
/sys/class/input/eventX/device/id/vendor and the product ID from
/sys/class/input/eventX/device/id/product .
The details for reading the event streams (just as if it was a file) are in header file
/usr/include/linux/input.h and described pretty well in an old two-part LinuxJournal article,
here and
here. The interface is extremely stable, and you do not need any special libraries to use it. It is the same across all (not too ancient) linux distributions. Just read the event device as if it was a binary file.
You do need superuser access rights (or modifications to the udev rule for that event device) to read the event stream, though. If you run your Java program with superuser rights (I wouldn't!), or if you modify the udev rules to allow the user your Java program runs as to read from the input device, you can do this in pure Java.
In your case, I would recommend writing a very small and compact daemon in C (I prefer C99), which would run as a system service (controlled by SysV init script, Upstart, runit, daemontools, or whatever your distribution uses). It will be responsible for locating the correct device (or devices!). It will do whatever initialization and translation that is necessary, although you probably need none.
The daemon will provide the inputs as messages, either via a named pipe, or -- my preferred for this -- a Unix domain datagram socket (DatagramSocket in Java, I believe). This way the daemon will provide only complete barcode messages, and the application side does not need to worry about the translation, details, or start/end stuff; it will always receive a complete (stream of) datagram(s), each being a full barcode.
The C daemon needed is almost trivial. (There are certain tricks, like how to read from multiple input devices using only a single thread efficiently, and how to queue and distribute the barcode messages to all connected clients. But nothing too serious.)
Personally, I'd take care to write it in a way which would allow you to use multiple scanners and multiple types of scanners at the same time. You might, for example, let the user configure a "name" for each scanner (based on either scanner-provided identifiers, or by USB connection path). Then, the client can ask the daemon for a list of currently-connected scanners, and filter (either in the client, or in the daemon) the scanning events it receives. It might not seem important right now, but having two or three scanners (one or more in fixed positions) may be a big improvement in ergonomics later on.
Note that the same scheme works for practically any HID-type device, not just barcode scanners. (I do believe fingerprint scanners, for example, could be similarly supported. As well as numeric keypads (for hand-typing the barcode number in problematic cases).)
I have done some input event programming myself (in C99), and a lot of daemon programming, but I don't have a barcode scanner, so I'm not exactly sure how they provide the information. (Just as a numeric string? With at least a final delimiter, e.g. a newline? Is there a starting delimiter?)
Hope this helps,