Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java 11 api usage prevents titanium being used on android and with Scala #133

Closed
jtownson opened this issue Jan 15, 2021 · 19 comments · Fixed by #138, #142 or #147
Closed

Java 11 api usage prevents titanium being used on android and with Scala #133

jtownson opened this issue Jan 15, 2021 · 19 comments · Fixed by #138, #142 or #147

Comments

@jtownson
Copy link
Contributor

Problem faced using on android
Calls such as com.apicatalog.jsonld.JsonLd.toRdf(...) instantiate a default DocumentLoader which has a dependency on Java 11's java.net.http.HttpClient. If the calling code tries to set options such as JsonLd.toRdf(...).loader(jdk8CompatibleLoader) this fails to circumvent the loading of Java 11 classes (because the default java 11 DocumentLoader instance is created eagerly).

Problem faced using from Scala
Scala projects still commonly use Java 8 as the runtime. The problem above thus causes incompatible class version errors.

Describe the solution you'd like
I recommend you refactor the code so that the core API is compatible with Java 8. For android, it would work if any concrete, default implementations which depend on Java 11 classes are not loaded in the case where the user provides overriding options. For Scala, I think you would have to actually compile under Java 8 (which would require reworking classes such as 'com.apicatalog.jsonld.loader.HttpLoader').

@filip26
Copy link
Owner

filip26 commented Jan 15, 2021

Hi,
thank you for opening this issue. Refactoring existing code to comply with deprecated Java 8 is not the way to go. Also, the future of Android Java is unclear to me. I'm not sure It's worth the effort right now and  I am very interested in how big the demand is.

Anyway, the code could be modularized, and for example HttpLoader could be implemented separately for Java 8 and 11.

@acoburn
Copy link

acoburn commented Jan 15, 2021

While there are plenty of projects that still use Java 8, I agree with @filip26 that refactoring this codebase to support Java 8 is not the way to go.

In fact, one of the appealing aspects of this codebase is its use of the Java 11 APIs (in particular java.net.http.HttpClient)

@jtownson
Copy link
Contributor Author

Okay, sure but is there a solution for android then?

@filip26
Copy link
Owner

filip26 commented Jan 16, 2021

jsonld-java project supports JSON-LD 1.0 and Java 8

@jtownson
Copy link
Contributor Author

I had a look through and, apart from the use of HttpClient, the only Java 11 dependencies are assorted use of new methods in java.lang.String and Map.Entry. The String/Map stuff would be straightforward to rework. My solution would therefore be to provide a different HttpLoader using OkHttp (https://square.github.io/okhttp/).

Happy to submit a PR with that change if you will accept it. If not, I can create a fork. Having JSON-LD 1.1 and an implementation of URDNA2015 is really helpful.

@filip26
Copy link
Owner

filip26 commented Jan 16, 2021

Contribution is welcome, but we need to restructure the project.

  • core (shared code)
  • java11 build (using java.net.http.HttpClient)
  • android build (using OkHttp)

Do you intend to maintain the Android build in the future?

@jtownson
Copy link
Contributor Author

@filip26 Thanks for that. Under that assumption that an android module is, in effect, a DocumentLoader implementation, perhaps a few other classes and some maven boilerplate then, yes, I'd be happy to maintain that part. Is there a chat channel on which we can go over the details?

@jtownson
Copy link
Contributor Author

I have submitted a draft PR (#137). It provides backwards compatibility but does not yet provide any modularisation.

@filip26
Copy link
Owner

filip26 commented Jan 18, 2021

@jtownson thank you for the PR.

I'm thinking about having multiple sources and using maven profiles.

e.g.

src/main/java - shared code
src/main/java11 - java11 specific code
src/main/android - android specific code

We can use build-helper-maven-plugin to add java11 sources (default profile) and android sources (android profile).

I'll setup gitter later today so we can discuss that.

@acoburn What do you think about this solution?

@jtownson
Copy link
Contributor Author

jtownson commented Jan 19, 2021

@filip26 I guess that move needs you or somebody with a good handle on what is going on in other project branches, but let me know if I can help in any way.

I note that the project is dependency free -- with the exception of jakarta-json -- so I've refactored the draft PR to only depend on JDK classes.

@filip26
Copy link
Owner

filip26 commented Jan 23, 2021

@jtownson Hi, I've created a new branch experiment/android-build. The PR has been re-based.

I'm not sure, using multiple source directories, build classifiers, and profiles is the right way to do that. But the main objective is to avoid having one generic core/shared artifact that is built with java8 and two other packages (java11, android) depending on that package. Downside is that any extension must be built separately for java11 and android. Any help, advice is welcome.

I tend to prefer android as the classifier instead of java8 or jdk1.8 just to put emphasis that this artifact is intended to be used on android and there is no official java8 support.

We can discuss changes online at Titanium Gitter if you like.

@filip26
Copy link
Owner

filip26 commented Jan 23, 2021

@jtownson the code is separated and compilable. Unfortunately your PR is not mergeable. I'm sorry for that, please let's discuss changes in advance next time.

You can implement src/main/android/jsonld/loader/HttpLoader using OkHttp and compile the android build with ./mvnw package -P android Also, src/main/android/jsonld/StringUtils needs to be implemented to get it work.

I expect that booth HttpLoaders will share something like AbstractHttpLoader, but it's ok to have two completely separate implementations for now.

@jtownson
Copy link
Contributor Author

@filip26 I've created a new PR, based on your maven changes and implementing the missing bits.

@filip26
Copy link
Owner

filip26 commented Jan 26, 2021

@jtownson that's great. thanks. I see it uses HttpURLConnection. Why not OkHttp as you have been proposing?

@jtownson
Copy link
Contributor Author

Well, I had noted the project was, thusfar, dependency free, which seems a good thing. Also, I could not really uncover any evidence to suggest the things okhttp could provide -- caching, pooling, compression, async calls, etc -- are actually needed yet.

@filip26
Copy link
Owner

filip26 commented Jan 26, 2021

To me, OkHttp is the main reason for making a special build. It's slightly faster and less buggy than HtttpURLConnection. OkHttp supports HTTP/2.0 but HttpURLConnection for Android does not, as far as I know.

@filip26
Copy link
Owner

filip26 commented Jan 26, 2021

@jtownson Anyway, I'm going to merge the PR into experiment/android-build branch so we can move forward.

@filip26 filip26 linked a pull request Jan 26, 2021 that will close this issue
@jtownson
Copy link
Contributor Author

@filip26 if you want the OkHttp version, I've pushed it to the head of experiment/android-build in my account. Feel free to pull it across.

@filip26 filip26 linked a pull request Feb 6, 2021 that will close this issue
@github-actions
Copy link

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days

@github-actions github-actions bot added the Stale label Feb 26, 2021
@filip26 filip26 removed the Stale label Feb 26, 2021
@filip26 filip26 linked a pull request Mar 3, 2021 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants