Some nio classes are unavailable while using 2.2.6 in Android.

Issue #149 resolved
Roy Liao created an issue

With 2.2.4, it's ok with this line of code in android AudioFile af = AudioFileIO.read(file);

However, if using 2.2.6, it throws the error: java.lang.NoSuchMethodError: No virtual method toPath()Ljava/nio/file/Path; in class Ljava/io/File; or its super classes (declaration of 'java.io.File' appears in /system/framework/core-libart.jar)

I did a bit of research, looks like android only support android 1.6 and java.nio.file.Path is only available in java 1.7.

So I wonder if it possible to provide a compatible way to support android?

Comments (26)

  1. Roy Liao reporter

    Actually I am running on 6.0.1. (Samsung S7 Edge)

    I just found a topic that mentioned this issue..

    http://stackoverflow.com/questions/24869323/android-import-java-nio-file-files-cannot-be-resolved

    "Android does not offer all classes that "conventional java" has to offer. Files is one of the classes, that Android doesn't offer."

    And another one.

    https://github.com/joel-costigliola/assertj-core/issues/345

    Would be possible to have any workaround for this..otherwise android developers might not be able to use versions from 2.2.6...

  2. Eric Snell

    This is an ongoing issue with jaudiotagger as Android is not considered when new code is developed. I ran into a similar, but much smaller, issue last year. Jaudiotagger does not provide an abstraction layer over java.nio.file classes and those are not currently supported in any Android version. Even if Google makes the previously mentioned move, there is an enormous install base for which this will stay an issue.

    If this version, and future versions, of jaudiotagger are to be used in the current Android install base, the new flac, aiff, and dsf readers and writers would need to be refactored. I've only just updated my fork and first (maybe only?) problems I see are a reliance on FileChannel features. I don't know how big of a change it would be.

    I'll take a quick look but I'm nearing a release. I'll update with what I find.

  3. Eric Snell

    At first glance I would say the refactoring necessary to support Android is non-trivial in that the AudioFileReader2 and AudioFileWriter2 use the nio Path class in framework methods in quite a few places.

    FileChannel construction could be moved to a utility method that hides how the Channel is constructed based on platform - RandomAccessFile on Android and FileChannel.open() in current implementation. Changing classes like Permissions to support Android would also be relatively trivial. There is also a reliance on the nio Files class, but I've not seen where that is extensive.

    However, the nio.Path issue requires design decisions that affect the framework methods. At first glance I don't see what Path provides to jaudiotagger that File does not, but that would be a sizable change. Of course the first 2 choices that come to mind are use File and not Path, unless Path is providing some functionality not provided by File, or create a facade over the implementation detail of Path v File.

    I'm releasing a beta of my app in the next few days that uses an older version of jaudiotagger. I'll come back to this issue when I can and try to size it and have some alternatives to support Android.

  4. Eric Snell

    No chance to work on it as of yet. First thing is I'll need to get the owner's opinion on how the change should be made (or if). Are the new classes wed to Java's Path or can it be reverted to File. If Path, can an abstraction be placed over Path/File to support the latest Java and Android. These classes, Path specifically, are weaved throughout the new framework for the new file types. The change appears non trivial depending on the strategy and what's found when all execution paths are traced. A fork needs to be avoided at all costs because there's a lot of good active development and defect fixes going on. I'm probably at least another week away from taking another look. Maybe we can get a comment from the owner until then? Is there a high desire to maintain Android compatibility? Waiting for Android support for these classes currently leaves out 100% of the install base and then when they do add support, the percentages will trickle for years as large portions of the install based are on old Android versions.

    There was talk in another thread about making jaudiotagger more data source agnostic, such that a layer on top would provide an abstraction of the data source. If that move is afoot, then this change might be moot. That would be the way to go but is a huge change.

  5. IJabz repo owner

    The move isnt so much File to Path but RandomAccessFile to Path, passing RandomAccessFiles was a mistake and moving to File/Path is neccessary. I Selected path because this overcome some deficiences in File and I didnt realize Android didnt support it. To be honest I would like to support Android but I only jaudiotagger myself on non-Android and so I dont want to restrict myself uneccessarily.

    Now there have been a number of requests to allow jaudiotagger to be used things other than files (such as #163 uris) so I think there is definently some sense in providing an abstraction that allows things other than files/paths , and this was part of the reason behind moving to AudioFileReader2 from AudioFileReader because that was not possible with AudioFileReaders reliance on RandomAccessFile and we have a datasource branch contributed by Silvano Riaz https://bitbucket.org/ijabz/jaudiotagger/branch/datasource but I havent had time to look at it.

    Eric, it would be great if you review this datasource branch and see if that would be a way forward.

  6. Eric Snell

    Great! I will when I am able. The thought of DataSource of course reminds of source/sink and sounds like it might be a good path. Too bad the okio folks don't support random access as they have a very nice light weight Source/Sink library that sits on top of java.io and java.nio that plays nicely in both a plain java and android world. A very minimimal io facade would then allow pluggable implementations and people could contribute implementations for, and optimized for, their needs.

    Is this branch buildable, functional, being maintained, or proof of concept? I need the new file types, want to stay current, and want it on Android so I'll help when I am able. Probably at least another week or so. Till then, I'll look when I have the chance. Thank you very much for the input as it gives a sense of direction.

  7. IJabz repo owner

    This branch was provided by another contributor in the last month, its not too far behind but I have not had chance to look at it yet but it maybe provide a way forward, unfortunately I have other priorities that I need to address first. Alternatively the first step is to complete the move from AudioFileReader/AudioFileWriter to AudioFileReader2/AudioFileWriter2 in the main branch, this needs to be done for mp3, mp4 and Wma. Once this is done we have removed the dependencies on RandomAccessFile, then should be eaiser to provide something in front of file/path/url ectera

  8. Theo Klink

    Has there been any further development in this area? I am using jaudiotagger-2.2.4-SNAPSHOT.jar but I want to be able to lift out the creation and writing of the audio file so that it can be used in Android api21 and above (with the new Storage Access Framework). Currently jaudiotagger cannot create/write to the external sdcard.

  9. Theo Klink

    Xerus, I managed to get jid3 working with the new framework but it only deals with mp3. I would like to be able to move to jaudiotagger completely

  10. Theo Klink

    On the Android 8 Features website, under "Updated Java language support": Android 8.0 (API level 26) adds support for several additional OpenJDK Java APIs: java.time from OpenJDK 8. java.nio.file and java.lang.invoke from OpenJDK 7.

    so I assume this resolves the issue. (apart from having to have 26 as the minSdk)

  11. IJabz repo owner

    okay im closing, reopen if there is an issue, I dont acually use android so it is not something I will test myself

  12. Xerus

    But having Android 8 / API Level 26 as minSdk level is absolutely unacceptable, you will reach very few people and I don't even have an Android 8 phone myself! But well, maybe I just have to read the tags on desktop and then sync them to mobile... but that's also meh as I can't edit them on mobile then...

    Also what changed between 2.2.4 and 2.2.6, maybe I'll be fine using the older version? Is there a changelog somewhere?

  13. Log in to comment