Importing java classes in Intellij Kotlin app - java

I am using IntelliJ for the first time to write a Kotlin program for windows.
I need to read a file so I used code from a sample site:
import java.io.File
import java.io.InputStream
fun main(args: Array<String>) {
val inputStream: InputStream = File("bezkoder.txt").inputStream()
val lineList = mutableListOf<String>()
inputStream.bufferedReader().useLines { lines -> lines.forEach { lineList.add(it)} }
lineList.forEach{println("> " + it)}
}
The thing is that it doesn't recognise the import for the java classes.
I guess it is something in my setup but I have no idea where to look and haven't managed to find an answer.
This is my SDK setup screen

You can't use Java SDK classes in the Kotlin/Native projects, only in Kotlin/JVM.
Please also make sure you have a valid JDK configuration in the project. See this answer for more details.
If you want to read a file in Kotlin Native, see CsvParser.kt example.

Related

How do I use JCEF with Intellij?

I've been trying to figure out if there is a way to use Chromium browser as the UI for a Java application. I found this IntelliJ page: https://jetbrains.org/intellij/sdk/docs/reference_guide/jcef.html The thing I can't figure out is how I actually use this in my project. My IntelliJ version is 2020.3 and it says that in 2020.2 JCEF was enabled by default. I however cannot figure out how I use JCEF in my project. I can't seem to find any clear documentation. When I try to import, for example, com.intellij it can't find the package.
Are there any tutorials or guides to integrate JCEF in my IntelliJ project?
You can run jetty server or use resource provider.
Example of resource provider:
https://medium.com/virtuslab/creating-intellij-plugin-with-webview-3b27c3f87aea
Also this example of abstract WebDialog explain how to pass data to fe:
https://github.com/sergeysenja1992/xm-online-idea-plugin/blob/master/src/main/kotlin/com/icthh/xm/actions/WebDialog.kt
All magic in class BrowserPipe (WebDialog.kt file) on backend side, and same class in frontend class
https://github.com/sergeysenja1992/xm-online-idea-plugin/blob/master/src/main/webapp/src/index.html
Next js file it's one more part of magic
<script src="http://registercallback/events.js"></script>
This js file does not exists, but be listen this request and return generated js code.
CefApp.getInstance().registerSchemeHandlerFactory("http", "registercallback", InjectJsHandlerFactory(inject()))
For more details pls look to this line of code in (WebDialog.kt file)
After all manipulation as result i have ability to write components in simple way:
FE: https://github.com/sergeysenja1992/xm-online-idea-plugin/blob/master/src/main/webapp/src/app/settings/settings.component.ts
constructor(private zone: NgZone) {
let w: any = window;
w.messagePipe.subscribe('initData', (res) => {
console.info('initData', res);
zone.run(() => {
this.updateData(res);
});
});
w.messagePipe.post('componentReady', 'SettingsComponent ready')
}
BE: https://github.com/sergeysenja1992/xm-online-idea-plugin/blob/master/src/main/kotlin/com/icthh/xm/actions/settings/SettingsDialog.kt
override fun callbacks(): List<BrowserCallback> {
val data = ArrayList(project.getSettings().envs.map { it.copy() })
this.data = data;
return listOf(
BrowserCallback("componentReady") {body, pipe ->
logger.info("Update ${body}")
pipe.post("initData", mapper.writeValueAsString(mapOf(
"updateModes" to updateModes,
"branches" to project.getRepository().getLocalBranches(),
"envs" to data,
)))
},
BrowserCallback("envsUpdated") {body, pipe ->
logger.info("envsUpdated ${body}")
val envs = mapper.readValue<List<EnvironmentSettings>>(body)
this.data = ArrayList(envs);
}
)
}

How to load a custom transformer in Spark 2.4

I'm trying to create a custom transformer in Spark 2.4.0. Saving it works fine. However, when I try to load it, I get the following error:
java.lang.NoSuchMethodException: TestTransformer.<init>(java.lang.String)
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getConstructor(Class.java:1825)
at org.apache.spark.ml.util.DefaultParamsReader.load(ReadWrite.scala:496)
at org.apache.spark.ml.util.MLReadable$class.load(ReadWrite.scala:380)
at TestTransformer$.load(<console>:40)
... 31 elided
This suggests to me that it can't find my transformer's constructor, which doesn't really make sense to me.
MCVE:
import org.apache.spark.sql.{Dataset, DataFrame}
import org.apache.spark.sql.types.{StructType}
import org.apache.spark.ml.Transformer
import org.apache.spark.ml.param.ParamMap
import org.apache.spark.ml.util.{DefaultParamsReadable, DefaultParamsWritable, Identifiable}
class TestTransformer(override val uid: String) extends Transformer with DefaultParamsWritable{
def this() = this(Identifiable.randomUID("TestTransformer"))
override def transform(df: Dataset[_]): DataFrame = {
val columns = df.columns
df.select(columns.head, columns.tail: _*)
}
override def transformSchema(schema: StructType): StructType = {
schema
}
override def copy(extra: ParamMap): TestTransformer = defaultCopy[TestTransformer](extra)
}
object TestTransformer extends DefaultParamsReadable[TestTransformer]{
override def load(path: String): TestTransformer = super.load(path)
}
val transformer = new TestTransformer("test")
transformer.write.overwrite().save("test_transformer")
TestTransformer.load("test_transformer")
Running this (I'm using a Jupyter notebook) leads to the above error. I've tried compiling and running it as a .jar file, with no difference.
What puzzles me is that the equivalent PySpark code works fine:
from pyspark.sql import SparkSession, DataFrame
from pyspark.ml import Transformer
from pyspark.ml.util import DefaultParamsReadable, DefaultParamsWritable
class TestTransformer(Transformer, DefaultParamsWritable, DefaultParamsReadable):
def transform(self, df: DataFrame) -> DataFrame:
return df
TestTransformer().save('test_transformer')
TestTransformer.load('test_transformer')
How can I make a custom Spark transformer that can be saved and loaded?
I can reproduce your problem in spark-shell.
Trying to find the source of the problem I looked into DefaultParamsReadable and DefaultParamsReader sources and I could see they utilize Java reflection.
https://github.com/apache/spark/blob/v2.4.0/mllib/src/main/scala/org/apache/spark/ml/util/ReadWrite.scala
lines 495-496
val instance =
cls.getConstructor(classOf[String]).newInstance(metadata.uid).asInstanceOf[Params]
I think scala REPLs and Java reflection aren't good friends.
If you run this snippet (after yours):
new TestTransformer().getClass.getConstructors
you'll get the following output:
res1: Array[java.lang.reflect.Constructor[_]] = Array(public TestTransformer($iw), public TestTransformer($iw,java.lang.String))
It is true! TestTransformer.<init>(java.lang.String) doesn't exist.
I found 2 workarounds,
Compiling your code with sbt and creating a jar, then including in spark-shell with :require, worked for me (You mentioned you tried a jar, I don't know how though)
Pasting the code in spark-shell with :paste -raw , worked fine as well. I suppose -raw prevents from REPL doing shenanigans to your classes.
See: https://docs.scala-lang.org/overviews/repl/overview.html
I'm not sure how you can adapt any of these to Jupyter but I hope this info is useful for you.
NOTE: I actually used spark-shell in spark 2.4.1

How can I set up Soot when using it as a library?

I want to use Soot library to build an SSA from *.java file. But all the examples I found use Soot as standalone tool, not library. Can anyone give me example hot to do it in program?
For a start I am just trying to load my class from the source file and print it (TestClass.class is in the directory A/home/abdullin/workspace/test):
import soot.G
import soot.Scene
import soot.options.Options
fun main(args: Array<String>) {
G.reset();
Options.v().set_whole_program(true)
Scene.v().loadBasicClasses()
Scene.v().sootClassPath = "${Scene.v().defaultClassPath()}:/home/abdullin/workspace/test"
val sc = Scene.v().getSootClass("TestClass")
Scene.v().loadNecessaryClasses()
sc.setApplicationClass()
println(sc.name)
sc.methods.forEach {
println(it)
}
}
But when I run this, I get runtime exception Aborting: can't find classfile TestClass. If I change Scene.v().getSootClass("TestClass") to Scene.v().loadClassAndSupport("TestClass") as they do in some of their tutorials, soot finds my class, but it is not complete. It prints me signatures of class methods, but can't find their bodies, activeBody field is null.
TestClass
<TestClass: void <init>()>
<TestClass: void main(java.lang.String[])>
<TestClass: void f1()>
First, make sure that the Soot jar is in the classpath.
Then, set up Soot using the classes soot.G and soot.options.Options (G.reset() and Options.v().parse() are methods of interest, also see command line options).
Using soot.Scene.v().setSootClassPath() and similar you can tell Soot where to find the class files of the code you want to analyze.
You can then use Scene.v().getSootClass() to obtain SootClass objects. Make sure that Soot loads all classes after setting the class you want to analyze as main class:
mySootClass.setApplicationClass();
Scene.v().loadNecessaryClasses();
After this, you can use Soot to obtain various types of graphs and run you analyses, as described in the Survivor's guide
You can read this post (https://o2lab.github.io/710/p/a1.html). But if you try to analyze a jar file, you should unzip it and get a set of class files. Then you should add your classes directory into the soot_class_path.
Demo:
public static void main(String[] args) {
//spotbugs -- testing
String classesDir = "D:\\wkspace\\seed8\\dir\\spotbugs";
String mainClass = "edu.umd.cs.findbugs.LaunchAppropriateUI";
//set classpath
String jreDir = System.getProperty("java.home") + "\\lib\\jce.jar";
String jceDir = System.getProperty("java.home") + "\\lib\\rt.jar";
String path = jreDir + File.pathSeparator + jceDir + File.pathSeparator + classesDir;
Scene.v().setSootClassPath(path);
//add an intra-procedural analysis phase to Soot
TestCallGraphSootJar_3 analysis = new TestCallGraphSootJar_3();
PackManager.v().getPack("wjtp").add(new Transform("wjtp.TestSootCallGraph", analysis));
excludeJDKLibrary();
Options.v().set_process_dir(Arrays.asList(classesDir));
Options.v().set_whole_program(true);
//Options.v().set_app(true);
SootClass appClass = Scene.v().loadClassAndSupport(mainClass);
Scene.v().setMainClass(appClass);
Scene.v().loadNecessaryClasses();
//enableCHACallGraph();
enableSparkCallGraph();
PackManager.v().runPacks();
}
If you replace
SootClass appclass = Scene.v().loadClassAndSupport(mainclass);
Scene.v().setMainClass(appclass);
Scene.v().loadNecessaryClasses();
by
Scene.v().loadNecessaryClasses();
SootClass appclass = Scene.v().getSootClass(mainclass);
Scene.v().setMainClass(appclass);
, the program also works.

Implementing ImageJ macro commands into an existing Plugin

I'm trying to change the existing plugin OpenComet for ImageJ. I'm not into Java, so perhaps it's an easy task.
What I'm trying to implement are the following things
run("Bio-Formats Windowless Importer", "open=path autoscale color_mode=Default view=Hyperstack stack_order=XYCZT");
opening my files with the help of the Bioformat Importer plugin
run("Flip Horizontally");
This is supposed to be placed into the following code:
// Iterate over each input file
for(int i=0;i<inFiles.length;i++){
// Try to open file as image
//NUMBER 1 BIOFORMAT IMPORT AT THIS POINT
ImagePlus imp = IJ.openImage(inFiles[i].getPath());
// If image could be opened, run comet analysis
if(imp!=null){
//NUMBER 2 FLIPPING AT THIS POINT
String imageKey = inFiles[i].getName();
Moreover I would need to import the class of the BioFormat Importer or something like this. Wouldn't I?
Thanks a lot in advance.
run("Bio-Formats Windowless Importer", "open=path autoscale
color_mode=Default view=Hyperstack stack_order=XYCZT");
opening my files with the help of the Bioformat Importer plugin
You can achieve this using the BF helper class of bio-formats (see its API documentation). For a javascript example, have a look here. In Java, this could look like:
import loci.plugins.BF;
[...]
ImagePlus[] imps = BF.openImagePlus(inFiles[i].getPath());
ImagePlus imp = imps[0];
run("Flip Horizontally");
Use the recorder (Plugins > Macros > Record...) in Java mode to get the required command:
import ij.IJ;
[...]
IJ.run(imp, "Flip Horizontally", "");
If you want to know the Java command at a lower level, use the Command Finder (press [L] or Plugins > Utilities > Find Commands...) and type "flip" and you'll find the class that implements the command:
ij.plugin.filter.Transformer("fliph")
Hope that helps.

Error reading image from scala playn

I researched and looked into the PlayN game framework and I liked it a lot. I program in Scala and actually don't know Java but it's not usually a problem since they work together great.
I've set up a basic project in eclipse and imported all the libraries and dependencies. I even translated over the base maven project code. Here's the two files:
Zeitgeist.scala
package iris.zeit.core
import playn.core.PlayN._
import playn.core.Game
import playn.core.Image
import playn.core.ImageLayer
class Zeitgeist extends Game {
override def init (){
var bgImage: Image = assets().getImage("images/bg.png")
var bgLayer: ImageLayer = graphics().createImageLayer(bgImage)
graphics().rootLayer().add(bgLayer)
}
override def paint (alpha: Float){
//painting stuffs
}
override def update(delta: Float){
}
override def updateRate(): Int = {
25
}
}
Main.scala
package iris.zeit.desktop
import playn.core.PlayN
import playn.java.JavaPlatform
import iris.zeit.core.Zeitgeist
object Main {
def main(args: Array[String]){
var platform: JavaPlatform = JavaPlatform.register()
platform.assets().setPathPrefix("resources")
PlayN.run(new Zeitgeist())
}
}
The cool thing is it works! A window comes up perfectly. The only problem is I can't seem to load images. With the above line, "assets().getImage("images/bg.png")" it pops out
Could not load image: resources/images/bg.png [error=java.io.FileNotFoundException: resources/images/bg.png]
I've played around with the location of my resources file to no avail. I was even able to find bg.png myself with java.io.File. Am I doing something wrong? Is there something I'm forgetting?
Looking at the code of JavaAssetsManager, it looks like it is trying to load a resource and not a file. So you should check that your images are actually in the classpath and at the path you give ("resources/images/bp.png")
Alternatively, you can use getRemoteImage and pass a File URL. As you succeeded in using a java.io.File, you can just get the URL with method toUri of File (toUrl is deprecated).
This almost certainly doesn't work because you're doing this:
platform.assets().setPathPrefix("resources")
That means you're saying your source folder looks like this:
src/main/resources/resources/images/bg.png
src/main/resources/resources/images/pea.png
src/main/resources/resources/images
I imagine it actually looks like one of these:
src/main/resources/assets/images/bg.png <-- 'assets' the default prefix
src/main/resources/assets/images/pea.png
src/main/resources/assets/images
or:
src/main/resources/images/bg.png <-- You have failed to put a subfolder prefix in
src/main/resources/images/pea.png
src/main/resources/images
You can either do this, if you have no prefix:
plat.assets().setPathPrefix("")
Or just put your files in the assets sub-folder inside the resources folder.
It's worth noting that the current implementation calls:
getClass().getClassLoader().getResource(...)
Not:
getClass().getResource(...)
The difference is covered elsewhere, but the tldr is that plat.assets.getImage("images/pea.png") will work, but plat.assets.getImage("/images/pea.png") will not.

Categories