I don't know which JVMs implement / don't implement direct ByteBuffers. But in a sense, it is not particularly relevant ... because it is always possible that some vendor will come out with a new JVM that changes the equation by supporting / not supporting direct ByteBuffers.
Should a JNI library always code for managed ByteBuffers and relegate direct ByteBuffers as an optimization?
It depends on your goal.
If your aim is for maximum portability then your JNI code should not assume that direct ByteBuffers are available.
If your goal is for maximum performance, then your code could assume that direct ByteBuffers will always be available (and break if it is not). Alternatively, you could have two different JNI libraries (or conditionally compiled variants of the same library) that the Java-side chooses between at runtime depending on the platform's support for direct ByteBuffers.
But this all seems a bit disconnected from reality. By going down the JNI route, you are implicitly taking the path of non-portability. You already have to deal with native libraries that (at least) have to be recompiled for different JVMs and different target platforms. And I'd have thought that testing on all supported platforms was essential.
In summary, don't expect any significant short-cuts for multi-platform support for your JNI code.