there is a way to generate thrift description file for existing java classes using refletion? Avro has that feature, but i need to use thrift and i have a lot of existing business class in java that i need to serialize in c++ and java.
Enter Swift: https://github.com/facebook/swift/
git clone https://github.com/facebook/swift
cd swift ; mvn package
In particular swift2thrift. Markup your classes as here: https://github.com/facebook/swift/
and run:
MY_CLASSES=$HOME/ExampleService/target/ExampleService-1.0-SNAPSHOT.jar # just an example
cd ~/ExampleService ; mvn compile package && java -cp ~/swift/target/swift2thrift-generator-cli-0.15.0-SNAPSHOT-standalone.jar:$MY_CLASSEScom.facebook.swift.generator.swift2thrift.Main -package net.mycompany ExampleService -map ExampleService path/to/base.thrift -namespace py mycompany.thrift -namespace java net.mycompany.thrift -namespace cpp mycompany
outputs Thrift .idls for existsing Java classes.
Also see: Can generate .thrift files from existing java/scala interfaces and data types?
Not from the library directly; thrift generates it's own classes and some validation code so that both "ends" (client/server) can inter-operate without error. You should write code to map your business objects to thrift objects.
Related
Kotlin script (.main.kts) files have the idea of providing executable Kotlin code in ONE single standalone file, which is immensely convenient for scripting or when sharing code snippets on StackOverflow for example. In contrast to that, currently almost all Java/Kotlin uses a build system (e.g. gradle) with cryptic build files and a deep folder structure.
While I like the Kotlin script idea a lot, it seems to be barely used, with only 22 questions on StackOverflow and extremely sparse documentation and precious few Google results. I am able to pull in dependencies using #file:DependsOn inside of the actual script rather than the traditional build file:
build.gradle:
dependencies {
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.0'
}
foo.main.kts:
#file:DependsOn("org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.0")
However, I can't find a way to use "apply plugin" in my .main.kts file. It's not used in any of the code snippets I found online.
build.gradle:
apply plugin: 'kotlinx-serialization'
foo.main.kts:
???
For reference, I attached an MWE below. The error message says the class Node is not serializable, but as pointed out in this question that message is misleading and the actual issue that apply plugin is missing, which I do not know how to use outside of a build.gradle file:
#file:DependsOn("org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.0")
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
#Serializable
data class Node (val numbers: List<Int>)
val h = Json.decodeFromString<Node>(""" {"numbers": [1, 2, 3]} """)
Run it on Ubuntu:
snap install kotlin
kotlin foo.main.kts
kotlinx-serialization is a Gradle plugin, which adds to pipeline same-named compiler plugin - it generates the serializer() method for classes annotated with #Serializable.
When you compile Kotlin code with kotlinc compiler, you can attach the plugin by providing the path to its JAR file (it's bundled with the compiler) using the -Xplugin=/snap/kotlin/current/lib/kotlinx-serialization-compiler-plugin.jar compiler option.
For .kts files, there is a #file:CompilerOptions annotation, but currently (in Kotlin 1.5.10) this particular key is not supported (warning: the following compiler arguments are ignored on script compilation: -Xplugin)
Command line
On the command line you may use
kotlinc -script -Xplugin="/snap/kotlin/current/lib/kotlinx-serialization-compiler-plugin.jar" foo.main.kts
Script header
As a workaround you may use this shebang:
#!/usr/bin/env -S kotlinc -script -Xplugin="/snap/kotlin/current/lib/kotlinx-serialization-compiler-plugin.jar"
To run your script you need to turn it into an executable:
chmod u+x foo.main.kts
Now it could be run with:
./foo.main.kts
This is very close to what I'm trying to accomplish. How to compile and run kotlin program in command line with external java library
I really want to learn how to compile and run simple code that includes libraries but am getting a bit lost when it comes to including classpaths.
I’m currently trying to compile and run
import kotlinx.serialization.*
import kotlinx.serialization.json.*
#Serializable
data class Project(val name: String, val language: String)
fun main() {
// Serializing objects
val data = Project("kotlinx.serialization", "Kotlin")
val string = Json.encodeToString(data)
println(string) // {"name":"kotlinx.serialization","language":"Kotlin"}
// Deserializing back into objects
val obj = Json.decodeFromString<Project>(string)
println(obj) // Project(name=kotlinx.serialization, language=Kotlin)
}
using
kotlinc -cp "C:\PROGRA~1\Kotlin\lib\kotlinx-serialization-runtime-1.0-M1-1.4.0-rc.jar" main.kt
to compile with this compiler
https://blog.jetbrains.com/kotlin/2020/07/kotlin-1-4-rc-released/
allowed lib at bottom of the article
that's where kotlinx-serialization-runtime-1.0-M1-1.4.0-rc.jar is coming from. I chose this runtime jar because when I use the new kotlin 4.0.21 compiler it requires the kotlin-serialization-runtime-1.0.1.jar which you need to build yourself but when I download the source and run gradle build it doesn't seem to get generated (separate problem but would love to know how to build the runtime jar myself)
when I try and run I get
Exception in thread "main" java.lang.NoClassDefFoundError: kotlinx/serialization/json/Json
at MainKt.main(main.kt:12)
at MainKt.main(main.kt)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.jetbrains.kotlin.runner.AbstractRunner.run(runners.kt:64)
at org.jetbrains.kotlin.runner.Main.run(Main.kt:149)
at org.jetbrains.kotlin.runner.Main.main(Main.kt:159)
Caused by: java.lang.ClassNotFoundException: kotlinx.serialization.json.Json
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:435)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
... 9 more
I know I need to include a classpath when I run
kotlin MainKt
but have tried everything with no success
I've tried many different combinations of things including
compiling with and without
-Xplugin="C:\PROGRA~1\Kotlin\lib\kotlinx-serialization-compiler-plugin.jar doesn't seem to make a difference so I left it off.
I have tried compiling to both a java .jar as well as a kotlin .class file both seem to need classpath information at runtime. I would rather compile to a kotlin .class and keep java out of this until I really need it. This way I can learn what java is really doing in my application.
I guess what I really want to know is how one can determine what is required at runtime for an executable to run. I found this site which helps show dependencies but is for older versions of kotlin https://kotlin.binarydoc.org/org.jetbrains.kotlin/kotlin-compiler-dist/1.3.71/package?package=kotlinx.serialization
I’ve also been peaking into the .class files using https://github.com/google/android-classyshark
and
https://github.com/borisf/classyshark-bytecode-viewer
but still when people tell others, on StackOverflow, what classpath they need to use to solve their problem it seems like magic. Can someone out there teach me how to fish without gradle?
p.s. If anyone has any good resources on learning the internals of how gradle is building the project. I've looked here a bit https://docs.gradle.org/current/userguide/userguide.pdf but didn’t seem to help. maybe I missed something. Also, this page https://kotlinlang.org/docs/reference/serialization.html#example-json-serialization seems to have what I need but can't seem to transfer that to what the command line needs.
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.1")
}
what does this mean? I think this is referring to this https://github.com/Kotlin/kotlinx.serialization
but then how can I build what I need from this repo and use it to allow my application to know where its runtime dependencies are? ugh. I really wanted to figure all this out myself, but I must kneel to the internet gods for this one. Sorry, my post is a mess. I love to learn.
It took some time but I was able to build and run the serialization sample found at https://github.com/Kotlin/kotlinx.serialization on the command line using the current kotlinc compiler and the kotlinx.serializtion.1.0.1 library.
Here are the direct links to the compilers and libs
kotlinc and kotlinc-native v1.4.20
https://github.com/JetBrains/kotlin/releases/tag/v1.4.20
Kotlinx.serialization v1.0.1
https://github.com/Kotlin/kotlinx.serialization/releases/tag/v1.0.1
These both can also be found in the 1.4.20 releases blog post under the section titled How To Update:
https://blog.jetbrains.com/kotlin/2020/11/kotlin-1-4-20-released/
Setting Up Katlin’s .jar Libraries
After updating my path to point to the new compilers I still needed to build the serialization libs. This was as simple as running gradle build in the root directory of the unzipped kotlinx-serialization-1.0.1 folder. Make sure to set your JAVA-HOME system variable before you do this or it won’t work.
Once it's built you need to grab both the kotlinx-serialization-json-jvm-SNAPSHOT-1.0.1.jar and the kotlinx-serialization-core-jvm-SNAPSHOT-1.0.1.jar files and move them into the project directory. This definitely confused me because I had found a runtime lib for kotlinx serialization on the MVN repository site that was one jar file, but I wasn't seeing it after building the 1.0.1 libraries. Once I extracted the 1.0.1 runtime jar I found online, by renaming the .jar to .zip, it became apparent that it consisted of both the contents of the core and json jars. Don’t use the kotlinx-serialization-1.0.1-SNAPSHOT.jar. This jar only contains a blank MANIFEST.ms file. You can find the kotlinx-serialization-core-jvm-1.0.1-SNAPSHOT.jar in the kotlinx.serialization-1.0.1\core\build\libs folder and the kotlinx-serialization-json-jvm-1.0.1-SNAPSHOT.jar in the kotlinx.serialization-1.0.1\formats\json\build\libs folder. anyways.
Compiling Your .jar Library
once you have the jars in your project folder you can build your project
I included my cleanbuildandrun.sh shell script down below for easy reference.
My first attempt 1) was to try and build the project without compiling it to a .jar library file. This was a complete failure. I got it to compile but running the project proved much harder. I was unable to tell kotlin where the libraries were at runtime. I tried so many different things Including trying to point it to a manifest file I created but nothing seemed to work. It seems you need to build an executable jar in order to make this work. which brings me to my second try 2). This is where I found more success.
Attempt 2)
First you need to include the kotlinx-serialization-compiler-plugin.jar using the "-Xplugin" compiler flag. My understanding is that plugins are used to define annotations to the compiler like #Serializable. You can find this jar file in the lib folder inside the compiler you just downloaded. I copied this into my projects /lib folder next to the other jar files to make things self-contained and portable.
Next you need to tell the compiler where to find the library classes you want to access using the "-classpath" or "-cp" compiler flag.
Make sure to include kotlin runtime libraries using the "-include-runtime" compiler flag. This will bundle the kotlin standard class libraries within your jar so you don’t need to point at them during runtime.
Last direct the compiler to build a jar file by providing the -d compiler flag with the name and extension of your soon to be .jar file. That’s it, your off compiling.
Example Shell Script:
#!/bin/bash
sh clean.sh
case $1 in
1) # Comming Soon
kotlinc -verbose -Xplugin="lib\kotlinx-serialization-compiler-plugin.jar" \
-cp "lib\kotlinx-serialization-json-jvm-1.0.1.jar;lib\kotlinx-serialization-core-jvm-1.0.1.jar" \
main.kt
;;
2) # Working
kotlinc main.kt -Xplugin="lib\kotlinx-serialization-compiler-plugin.jar" \
-cp "lib\kotlinx-serialization-json-jvm-1.0.1.jar;lib\kotlinx-serialization-core-jvm-1.0.1.jar" \
-include-runtime -d main.jar
jar ufm Main.jar ManifestAdditions.txt lib
kotlin main.jar
;;
3) # Comming Soon
kotlinc-native main.kt -verbose -Xplugin="lib\kotlinx-serialization-compiler-plugin.jar" \
-cp "lib\kotlinx-serialization-json-jvm-1.0.1.jar;lib\kotlinx-serialization-core-jvm-1.0.1.jar" \
-manifest ManifestAddition.txt -o main
;;
esac
Running your .jar Library
By default, when you compiled the jar it created a MANIFEST.ms file that it uses to tell your jar library where the entry point is. which would be enough if we weren’t using additional libraries in our application. So next we need to add those libraries to the jar file we compiled while at the same time updating its MANIFEST.ms file to tell it where those libraries are within that jar file. We can use the cli tool jar to accomplish this. With the command:
jar ufm Main.jar ManifestAdditions.txt lib
we are able to update the current jar file.
u - tells jar we want to update an existing jar file
f - indicates that we are providing the jar file we want to update on the cmd line
m - indicates that we will be providing the manifest file
The Manifest .txt file should look like this:
Main-Class: MainKt
Class-Path: lib\kotlinx-serialization-core-jvm-1.0.1.jar lib\kotlinx-serialization-json-jvm-1.0.1.jar
Make sure to add a new line at the end of the file or it won’t parse the Class-Path.
That’s it. Now we have an executable jar file that we can use to run our serialization code on the command line:
kotlin main.jar
should output:
{"name":"kotlinx.serialization","language":"Kotlin"}
Project(name=kotlinx.serialization, language=Kotlin)
Post Mark
I would really like to turn this answer into a blog post that explains how to use the kotlin compiler, with libraries, on the command line. The information is out there but it seems to be scattered. I would like to include how to compile and run without using jar files, if that’s even possible, as well as how to compile and run using the native compiler. If anyone can help fill in these gaps it would be much appreciated. I think this information could help others learn how to set up simple test environments so they can better understand the functionality of these libs without having to set up a build script. This will be my first attempt at creating a tutorial type blog post so any information would really help.
Is it possible to import classes from kotlinx package in a simple Kotlin script?
myscript.kts:
import kotlinx.serialization.*
import kotlinx.serialization.json.*
println("")
Running the above script with kotlinc -script myscript.kts gives this error:
error: unresolved reference: kotlinx
When I checked kotlinc/lib/ directory, there exists kotlinx-coroutines-core.jar and so on.
I am using Kotlin compiler version 1.4.0.
You can execute kotlin like a simple bash script with dependencies if you change the name to *.main.kts
https://raw.githubusercontent.com/yschimke/okurl-scripts/master/commands/tube-status.main.kts
$ ./tube-status.main.kts
Good Service
Good Service
Minor Delays
Part Closure
Minor Delays
Good Service
Minor Delays
Good Service
Part Closure
Good Service
Planned Closure
First of, the imports you have are related to the kotlin serialization library not the coroutines one.
As for running your script you need to specify the dependencies to the compiler. You can run your script like this :
kotlinc -script myscript.kts -classpath kotlinx-serialization-runtime-0.20.0-1.4.0-rc-95.jar
I've used the old kotlin serialization runtime but you'll need to adapt the command to your needs.
I am new to Java Agent DEvelopment Framework for developing Agents.
I used to work with Jade using Eclipse, I've created some agents I converted my file to .jar format. But now I want to test my .jar file by creating multiple agents.
How can I create one or multiple Jade agents using a command line ?
Please check the tutorials before asking such questions. Visit the Help Center and read about how to ask good questions.
But nevertheless,To create an agent using command the command line use:
java -cp lib\jade.jar;classes jade.Boot -gui -agents ping1:examples.PingAgent.PingAgent
java jade.Boot -agents "a:agents.AgentClass;b:agents.AgentClass".
Note that the classpath includes JADE classes (lib\jade.jar) and the previously compiled classes of the examples (classes). Note also that the value of the -agents option takes the form:
<agent-local-name>:<fully-qualified-agent-class>
Using JADE terminology, this is called an "Agent Specifier". More than one agent can be started by just typing several agent specifiers separated by a semicolon (';') as in the example below:
java -cp lib\jade.jar;classes jade.Boot -gui -agents ping1:examples.PingAgent.PingAgent;ping2:examples.PingAgent.PingAgent
From the perspective of your personal workflow it is probably not very comfortable to build the jar file each time you want to test your agents. The better way for debugging is to use the eclipse debug capabilities.
For this, place the jade.jar (and other required libraries) in your eclipse project. Further, configure the Java project to include these libraries in your project. After this you should be able to configure a debug configuration, where jade.Boot should be the main class, while the further Jade options (for agents or services) can be placed in the start argument tab (hope this rough description is enough).
Jetbrains provides some documentation but I can't find how to run compiled class file of Kotlin.
hello.kt:
fun main(args : Array<String>) {
println("Hello, world!")
}
compile:
$ kotlinc -out dist -src hello.kt
$ ls dist
namespace.class
$ java dist/namespace
Exception in thread "main" java.lang.NoClassDefFoundError: dist/namespace (wrong name: namespace)
$ java -jar /usr/local/kotlin/lib/kotlin-runtime.jar
Failed to load Main-Class manifest attribute from
/usr/local/kotlin/lib/kotlin-runtime.jar
How to run Kotlin program?
Knowing the Name of Your Main Class
Currently (Kotlin since M14 including up to 1.0 betas), to run a Kotlin class you are actually running a special class that is created at the file level that hold your main() and other functions that are top-level (outside of a class or interface). So if your code is:
// file App.kt
package com.my.stuff
public fun main(args: Array<String>) {
...
}
Then you can execute the program by running the com.my.stuff.AppKt class. This name is derived from your filename with Kt appended (previous versions appended KT but from later betas and 1.0 is Kt). You can change the name of this class within the file by adding this file-targeted annotation:
#file:JvmName("MyApp")
Or you can also put your main() into a class with a companion object and make it static using the JvmStatic annotation. Therefore your class name is the one you chose:
// file App.kt
package com.my.stuff
public class MyApp {
companion object {
#JvmStatic public fun main(args: Array<String>) {
...
}
}
}
Now for either of these methods, you just run the class com.my.stuff.MyApp
What other JAR files do I need?
You need your application JAR and any dependencies. For Kotlin specific JARs when outside of Maven/Gradle you need a Kotlin distribution which contains:
kotlin-runtime.jar (combined runtime and stdlib)
kotlin-reflect.jar only if using Kotlin reflection
kotlin-test.jar for unit tests that use Kotlin assertion classes
Within Maven/Gradle currently there is also a separate kotlin-stdlib.jar
Running from Intellij
If in Intellij (if it is your IDE) you can right click on the main() function and select Run, it will create a runtime configuration for you and show the fully qualified class name that will be used. You can always use that if you are unsure of the name of the generated class.
Running from Gradle
You can also use the Gradle Application plugin to run a process from Gradle, or to create a runnable system that includes a zip/tgz of your JAR and all of its dependencies, and a startup script. Using the example class above, you would add this to your build.gradle:
apply plugin: 'application'
mainClassName = 'com.my.stuff.AppKt'
// optional: add one string per argument you want as the default JVM args
applicationDefaultJvmArgs = ["-Xms512m", "-Xmx1g"]
And then from the command-line use:
// run the program
gradle run
// debug the program
gradle run --debug-jvm
// create a distribution (distTar, distZip, installDist, ...)
gradle distTar
Running Directly from Java Command-line
If you have a runnable JAR, and assuming KOTLIN_LIB points to a directory where Kotlin runtime library files reside:
java -cp $KOTLIN_LIB/kotlin-runtime.jar:MyApp.jar com.my.stuff.AppKt
See the notes above about other JAR files you might need. A slight variation if you have a runnable JAR (with the manifest pointing at com.my.stuff.AppKt as the main class):
java -cp $KOTLIN_LIB/kotlin-runtime.jar -jar MyApp.jar
Running using the Kotlin command-line tool
If you install Kotlin tools via Homebrew or other package manager. (on Mac OS X brew update ; brew install kotlin) Then it is very simple to run:
kotlin -cp MyApp.jar com.my.stuff.AppKt
This command adds the runtime to the classpath provided, then runs the class. You may need to add additional Kotlin libraries as mentioned in the section above "Running from Java."
Creating runnable JAR with the Kotlin compiler
This is not very common since most people use other build tools, but the Kotlin compiler can create a runnable Jar that solves this for you (see http://kotlinlang.org/docs/tutorials/command-line.html) when it bundles the runtime and your code together. Although this isn't as common when using tools such as Maven and Gradle, or IDE builds. Then run using the normal Java:
java -jar MyApp.jar
We ran into the same program and blogged our solution here: http://blog.ocheyedan.net/blog/2012/02/19/running-kotlin-code/
Basically you just need to invoke java with the -cp and the main class of 'namespace'. From your question, the java invocation would look something like this:
java -cp /usr/local/kotlin/lib/kotlin-runtime.jar:dist/namespace.class namespace
Update: In the newer versions of the Kotlin IDE plugin, you can use context Run-actions in the Editors pop-up menu.
If you are in the IDE, right-click the editor and choose "Run namespace"
Otherwise, compile and run the *.namespace class as a normal Java class.
I'm run jar which use kotlin like this
java -cp target/idea_test-1.0-SNAPSHOT.jar:lib/kotlin-runtime.jar testing.first seyfer
Hello seyfer
seed!
The docs give a nice and concise answer:
kotlinc hello.kt -include-runtime -d hello.jar
java -jar hello.jar
koclinc is located inside your IntelliJ IDEA directory
under IntelliJ\plugins\Kotlin\kotlinc\bin.
If you are running Windows use kotlinc-jvm.bat