1

I'm using this: https://github.com/tidalwave-it/jrawio-src It's an Image I/O SPI Provider for Camera Raw files

I ran the maven project, took the necessary jars it has generated and put them as Referenced Libraries into my own project that converts images. When I run a conversion of a .NEF format to JPEG the bellow error happens.

   Jan 22, 2020 1:54:16 PM it.tidalwave.imageio.util.Logger info
    INFO: Installing RAWProcessor...
    Jan 22, 2020 1:54:16 PM it.tidalwave.imageio.util.Logger info
    INFO: Installed RAWProcessor
    RAWProcessor succesfully installed
    Exception in thread "AWT-EventQueue-1" java.lang.NoSuchMethodError: java.nio.ShortBuffer.position(I)Ljava/nio/ShortBuffer;
        at it.tidalwave.imageio.nef.NEFCompressionData.<init>(NEFCompressionData.java:79)

and 79 is the line causing the error:

73        shortBuffer = byteBuffer.asShortBuffer();
79        shortBuffer.position(1);

Upon my research the referenced Buffer methods (such as shortBuffer.position(1);) used in the jrawio SPI have undergone changes from Java8 to Java9 and therefore it wouldn't be recognized - but I don't use Java9. I used Java8 for both editing and running the jrawio maven project and my own project.

I've been also trying to use and compile with older Javas but that breaks my own project. I've been changing the settings in generate-sources.xml and the pom.xml before running the jrawio project to generate the jars but no luck.

Running the jrawio project also gives:

warning [options] bootstrap class path not set in conjunction with -source 8

What can I do to fix all of this and successfully implement this Image I/O SPI Provider for Camera Raw files into my own project edited and compiled by Java8?

Josef
  • 13
  • 3
  • Can you double check which jdk you used to compile jrawio? The warning seems to indicate it was a version > 8 used during compilation and that could cause issues when later running against an older runtime. – Jörn Horstmann Jan 22 '20 at 13:57
  • @JörnHorstmann Hi. I think I did that on purpose - in the generate-sources.xml and the pom.xml of jrawio I set the source and target to 1.8 (Java 8 - right?). I did that because that's the version I'm using in Eclypse, in my image converting project/program - (JavaSE-1.8 library and then in my project's Properties, in Java Compiler I have ticked "Use compliance from execution environment 'JavaSE-1.8' on the 'Java Build Path'"). If I do "java -version" in terminal (Ubuntu) I see the system is using Java11 – Josef Jan 22 '20 at 14:38
  • When you work with maven projects you need to remember: 1) File -> Project Structure -> Project SDK should be set on your desire. 2) in pom xml file runtime and compiled should be matched to SDK set in step 1 under target tag. – Malakai Jan 23 '20 at 09:14

1 Answers1

0

As you noticed, the Buffer classes were changed in java9 to add covariant overrides of several methods. Previously, the method

public Buffer position(int newPosition)

only existed in the Buffer base class and because it also returned Buffer it was not as convenient to use combined with method chaining. In java9, overloaded methods were added to all subclasses to return the concrete subtype, for example

public ShortBuffer position(int newPosition)

This in itself is a compatible change, code compiled against the old method would contain a reference to that method and at load time it would be resolved against the concrete overload.

A problem occurs when code is compiled with the class files from jdk9 and run on an older jdk. In this case the bytecode contains a reference to the new overload, which can not be resolved on the older jdk.

This is also the cause of the warning you saw:

warning [options] bootstrap class path not set in conjunction with -source 8

The source and target options only affect the accepted source code and generated bytecode, but compilation would still use the class libraries of the current jdk. One solution to that would be to set the boot classpath to point to an older jre version.

A better solution, that was included in jdk9, is to the use release parameter instead. This makes the compiler use some kind of internal database that contains information about when which methods were added to the jdk, and generate bytecode compatible with a release version. With maven this parameter can be set using the maven.compiler.release property inside the properties block in pom.xml.

<properties>
    <maven.compiler.release>8</maven.compiler.release>
    ...

With ant, which is used to run the generate-sources.xml, the release parameter can be passed to the javac task

(Note that I did not actually test this with the jrawio sources)

Jörn Horstmann
  • 33,639
  • 11
  • 75
  • 118
  • Ok, so the jrawio is actually using the jdk9+ version of the Buffer classes therefore when I compile them with jdk8 it causes the error on run time. I thought it was the other way around! :D Anyway, due to my inexperience I'm having trouble figuring out where do the property with the release parameter go. – Josef Jan 22 '20 at 18:17
  • Added a bit more details about the maven and ant config, hope this helps – Jörn Horstmann Jan 23 '20 at 08:58
  • Adding `8` to the properties of the pom.xml solved the issue. Thank you so SO much! I have learned a lot through out all of this! – Josef Jan 23 '20 at 14:31