Open jmfayard opened 8 years ago
Hi @jmfayard, thanks for raising this. I've written some thoughts on #598 and this same applies to this one. Feel free to add comments there. Cheers.
Wanted to raise the same issue, but found this one. Thanks for explaining in #598.
@jmfayard what I do is that I create a Java class with jsonschema2pojo and let IntelliJ (or in my current case Android Studio) convert that class to Kotlin. Then all I do is to make it a data class, change the curly brackets to curved ones, add a comma after each variable, and if required make the objects non-null. This still saves me a lot of time.
I do have one question for Kotlin users: is there any viable way to generate Kotlin right now from outside Intellij? It seems like Jetbrains are keeping it there for now :(
I am not sure what you mean by 'generate'. Square has a tool to generate Kotlin files: kotlinpoet. Is this what you're looking for?
In #769 you asked for a way to generate Kotlin code outside of IntelliJ. Today I discovered that https://try.kotlinlang.org has a button 'Convert from Java', maybe this is what you're looking for.
@simontb Ooh, exciting. I wonder if that whole site is in GitHub.
I guess given that JetBrains runs the language, and Intellij, they may have given themselves their own hook into the IDE functionality. Good find though.
It would be cool to include the @Parcelize annotation on this feature if ever implemented. I also would like to participate.
+1
+1
want this
+1
+1
I do have one question for Kotlin users: is there any viable way to generate Kotlin right now from outside Intellij? It seems like Jetbrains are keeping it there for now :(
@joelittlejohn You might find this answer on StackOverflow helpful: https://stackoverflow.com/a/31498603
Basically, the answer refers to a unit test for the j2k module in the Kotlin repository on GitHub. That's the module responsible for the functionality that allows conversion of Java code to Kotlin code within IntelliJ IDEA. As this functionality is part of the community edition of IntelliJ IDEA, the source code of the j2k module is apparently available under the Apache 2 license, just like jsonschema2pojo. That means you should be able to integrate the j2k code into jsonschema2pojo without any legal problems. π
However, it might be preferable if someone packages the j2k module as a separate library and pushes it to Maven Central, so you can easily keep it up-to-date with upstream. I'm frankly surprised no one has done this yet.
I really hope you'll be able to implement Kotlin support in jsonschema2pojo soon. There are many JSON to Kotlin data class converters out there, but none of them seem to support JSON Schemas. Your project is apparently the only one that supports the generation of POJOs based on JSON Schemas. Having to work with POJOs without null safety really sucks. And the lack of Lombok support in jsonschema2pojo rules that out as an alternative. π
Here's the direct link to the j2k code: https://github.com/JetBrains/kotlin/tree/master/j2k
Please let us know if we can help you with this in any way. Thanks again for the hard work on this project. I hope this writing doesn't come off as ungrateful. It's just that your project could be even more awesome if it supported the automatic generation of Kotlin data classes with automatic native null-safety for required JSON properties. Please make this happen! Thanks. βΊοΈ
Thanks @volkert-fastned. I'd love to get Kotlin and Lombok support in.
It bugs me when the ecosystem of core tools around a language is tied tightly to a specific IDE. I'd love to see things like j2k spun out as re-usable libraries as you describe. Maybe you could do that?
I'll see what I can do.
@joelittlejohn Since we're having a Hackathon this week, it seemed like a good opportunity to dive into this today. π
So I started by building the j2k module of the (quite large) Kotlin code base. It took a long time just for j2k to build, since it apparently had a lot of dependencies on its sibling modules, requiring them to be built as well. However, I managed to build what I thought was a nice standalone JAR. I used mvn install:install-file
to install the JAR to my local Maven repository in ~/.m2
, after which I included the JAR as a Maven dependency in another project, in which I then tried to successfully call JavaToKotlinConverter.filesToKotlin()
, as described in that StackOverflow answer I referred to earlier.
Unfortunately, the code in j2k appears to be very tightly coupled with Jetbrains/IntelliJ code. π For one thing, it expects some kind of IDE context to work in, including an instance of the interface Project
, which I assume is supposed to represent an actual opened project in IntelliJ IDEA. I tried both using the provided MockProject
implementation and implementing the Project
with a stub. I didn't get either to work. While running my unit tests in which I was trying out the code, I kept getting "Method not Found" exceptions w.r.t. Picocontainer
. I tried adding Picocontainer as a dependency and then downgrading it to an older version, but all of that didn't work either.
Long story short, I spent the better part of the day trying to use the j2k code as a standalone library, but I was not successful. I tried diving a bit further into the code, in an attempt to peal off the layers and to see if I could perhaps find some more generic or independent class/code conversion logic underneath that I could perhaps access or reuse directly. For that, I opened the kotlin project in IntelliJ IDEA. Unfortunately, the project is so huge, that I had to wait for about half an hour to index all the files, even on a pretty fast system with lots of RAM. I studied it in detail yet, but so far, even at a lower level, the functionality really seems to tie in pretty intricately with Jetbrains IDE frameworks.
The test code that the StackOverflow answer referred to apparently makes use of a lot of framework mocking code in order to work programmatically outside of an IDE. Perhaps this test/mocking framework could somehow be used as application code and wrapped in a standalone library, but it doesn't appear trivial. This will take quite a bit of work.
I guess that was to be expected. After all, if the j2k code had been easy to use standalone, someone (perhaps even Jetbrains themselves) would probably have already published it as a library to Maven Central by now. Β―\_(γ)_/Β―
Of course, it may be possible that I overlooked some very obvious solutions w.r.t. getting j2k to work as a standalone library. Anybody who has any more and/or better insights on this, please chime in!
I also googled a bit for some other possible projects that could convert Java to Kotlin conversation independently from an IDE. I found something called kj2k, but that project hasn't been worked on for 7 years.
At this point, I wonder whether it would actually be less effort to just write something that can convert JSON Schemas straight to Kotlin code, preferably Kotlin data classes. There are several third party projects that can convert JSON (but not JSON Schemas) to Kotlin data classes. Perhaps those could be extended to support JSON Schemas as input as well. Or alternatively, perhaps we should just implement a clean JSON Schema to Kotlin data class converter as part of jsonschema2pojo.
What do you think?
By the way, for anyone wanting to investigate this further, this is what I did to build the j2k JAR(s) independently (using JDK 8):
git clone https://github.com/JetBrains/kotlin.git
cd kotlin/j2k/
JAVA_HOME=/path/to/jdk8 JDK_18=/path/to/jdk8 ../gradlew clean build
JAVA_HOME=/path/to/jdk8 JDK_18=/path/to/jdk8 ../gradlew test
JAVA_HOME=/path/to/jdk8 JDK_18=/path/to/jdk8 ../gradlew jar
mvn install:install-file -Dfile=build/libs/j2k-1.3-SNAPSHOT.jar -DgroupId=org.jetbrains.kotlin -DartifactId=j2k -Dversion=1.3-SNAPSHOT -Dpackaging=jar
# Wasn't sure what groupId to use here, since the JAR contains code in multiple packages.
mvn install:install-file -Dfile=dependencies/repo/kotlin.build/intellij-core/183.5153.4/artifacts/intellij-core.jar -DgroupId=org.jetbrains -DartifactId=intellij-core -Dversion=183.5153.4 -Dpackaging=jar
Then I added these locally installed dependencies to the POM of a separate project to try consuming the library:
<dependency>
<!-- I added this dependency later, when I started getting runtime errors, but it didn't help. -->
<groupId>org.picocontainer</groupId>
<artifactId>picocontainer</artifactId>
<!-- I tried version 2.2 as well, that didn't work either. :-( -->
<version>2.15</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>intellij-core</artifactId>
<version>183.5153.4</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>j2k</artifactId>
<version>1.3-SNAPSHOT</version>
</dependency>
@volkert-fastned Thank you for this amazing write up! I can imagine how thankless this task was, particularly when you find some new layer of interconnectedness with Intellij that ruins all your progress :) It's so disappointing when useful language tools are tightly bound into a IDE like this, but thanks for investigating so thoroughly.
So yes, I think the answer is kotlinpoet, and to introduce some kind of abstraction in jsonschema2pojo to allow the target language to be swapped based on configuration. I'm sure we'd get better Scala this way too :)
This brings me back to my original comment on #598 though. This idea may well be better implemented as an entirely new project.
@volkert-fastned Thank you for this amazing write up! I can imagine how thankless this task was, particularly when you find some new layer of interconnectedness with Intellij that ruins all your progress :)
Yeah, Hackathon projects are usually more fun than this. π But I'm glad I at least took a stab at it, even if for no other reason than to rule it out.
It's so disappointing when useful language tools are tightly bound into a IDE like this, but thanks for investigating so thoroughly.
I absolutely agree. Why not offer something this useful as a reusable library? π This code is part of the IntelliJ IDEA Community Edition, so it's not like it's a closely guarded proprietary feature. If anything, it would benefit the Kotlin ecosystem and community even more! Hmmm... Perhaps one of us should just open a feature request in their YouTrack issue tracker. "Please decouple and refactor j2k to a standalone library." π€
So yes, I think the answer is kotlinpoet, and to introduce some kind of abstraction in jsonschema2pojo to allow the target language to be swapped based on configuration. I'm sure we'd get better Scala this way too :)
This brings me back to my original comment on #598 though. This idea may well be better implemented as an entirely new project.
KotlinPoet looks interesting indeed. When you suggest a new project or a fork from jsonschema2pojo, do you also mean the Scala stuff, since you foresee a solution that would work well for both Scala and Kotlin? Or am I misunderstanding you?
Your comments in issue #598 seem to already answer my question. I was just wondering, since jsonschema2pojo already has partial Scala support.
Anyway, Scala is outside the scope of what I'm focusing on (Kotlin), so as a next step I'm going to see how easy it will be to write a rudimentary JSON Schema to Kotlin data class converter. I'll shamelessly steal whatever code from jsonschema2pojo I can reuse for this. This hackathon might prove to be fun yet. π
Thanks again!
@joelittlejohn Even though there doesn't appear to be a "quick fix" solution for implementing Kotlin support in jsonschema2pojo for the time being, implementing proper Lombok support and proper @Nullable
annotations (see https://medium.com/quick-code/the-case-of-npe-in-interop-between-java-and-kotlin-8790b2b73e18) would result in POJOs that would be much less painful and more convenient to use from within Kotlin JVM projects. After all, Lombok pretty much provides the same advantages as Kotlin data classes do. Of course this would only be the case for Kotlin JVM projects. For Kotlin Native, Kotlin.js and Kotlin Multiplatform projects, Lombok support would be useless and only generated native Kotlin code would work.
Long story short, once #166 is implemented, the generated POJOs will be practical for use in most Kotlin (JVM) projects.
+1
Hello, Would it be in the scope of this project to add support for the Kotlin programming language .
Given the example available at http://www.jsonschema2pojo.org, it would generate the following data class
If that's the case, since jsonschema2pojo is a pretty useful tool, I would be interested in participating to add this feature