How to capture output of exec-maven-plugin? - java

I'm trying to use the exec-maven-plugin as a way to integrate a 3rd party Java API. I'm using the exec:java goal to call my java main class. I need to parse the output of the API, however I do not see anything specific in the plugin that allows for this.
Is there a way in maven and/or the exec-maven-plugin to capture/save the output of the executions?

With the exec:exec goal, you can use the outputFile parameter (or using the command line property exec.outputFile).

Related

How to use Maven to encrypt a password — from Java?

I want to encrypt a password with maven, from within a Java program. Basically, I want to achieve the equivalent of calling mvn --encrypt-password p4ssw0rd, but without dropping to the command line.
I've looked into Apache Maven Invoker. I've found setters on InvocationRequest for _some command line options, such as InvocationRequest.setShowVersion(..) for --show-version. But I can't find one for --encrypt-password.
Is there a way to do this, either with Apache Maven Invoker or another way? I do not want to drop to or call a command line directly, since I want to be platform independent.
How do I invoke mvn --encrypt-password p4ssw0rd from a Java program?
It looks like you can use the plexus-cipher library, which is apparently what Maven uses to do the encryption.
See the code at https://github.com/sonatype/plexus-cipher
The unit tests will probably be enut to get you started.

How can I run Kotlin-Script (.kts) files from within Kotlin/Java?

I noticed that IntelliJ can parse .kts files as Kotlin and the code editor picks them up as free-floating Kotlin files. You are also able to run the script in IntelliJ as you would a Kotlin file with a main method. The script executes from top to bottom.
This form is PERFECT for the project I'm working on, if only I knew an easy way to use them from within Java or Kotlin.
What's the idiomatic way to "run" these scripts from Java or Kotlin?
Note that script files support in Kotlin is still pretty much experimental. This is an undocumented feature which we're still in the process of designing. What's working today may change, break or disappear tomorrow.
That said, currently there are two ways to invoke a script. You can use the command line compiler:
kotlinc -script foo.kts <args>
Or you can invoke the script directly from IntelliJ IDEA, by right-clicking in the editor or in the project view on a .kts file and selecting "Run ...":
KtsRunner
I've published a simple library that let's you run scripts from regular Kotlin programs.
https://github.com/s1monw1/KtsRunner
Example
The example class
data class ClassFromScript(val x: String)
The .kts file
import de.swirtz.ktsrunner.objectloader.ClassFromScript
ClassFromScript("I was created in kts")
The code to load the class
val scriptReader = Files.newBufferedReader(Paths.get("path/classDeclaration.kts"))
val loadedObj: ClassFromScript = KtsObjectLoader().load<ClassFromScript>(scriptReader)
println(loadedObj.x) // >> I was created in kts
As shown, the KtsObjectLoader class can be used for executing a .kts script and return its result. The example shows a script that creates an instance of the ClassFromScript type that is loaded via KtsObjectLoader and then processed in the regular program.
As of 2020 (Kotlin 1.3.70), you can just use the straightforward
kotlin script.main.kts
Note that using the file extension .main.kts instead of .kts seems to be important.
Note that for me this does not seem to run the main() function if defined, I had to add a manual call to main() at the top level.
One of the advantages of Kotlin script is the ability to declare code and dependencies inside a single file (with #file:DependsOn, see for example here)
early 2020ies kscript that you find at https://github.com/holgerbrandl/kscript
seems to be the most convenient and well supported way to go ...
jgo can fetch and run code from Maven repositories, so can be used to invoke
https://github.com/scijava/scijava-common and https://github.com/scripting-kotlin to execute a local Foo.kt like so:
jgo --repository scijava.public=maven.scijava.org/content/groups/public org.scijava:scijava-common:#ScriptREPL+org.scijava:scripting-kotlin Foo.kt
If no Foo.kt is provided, it launches a Kotlin REPL.

How to use jnaerator in a sbt project

I work on a Scala project that uses c++ code, using sbt. Once compiled, this c++ code is imported into Scala through Java code that uses jna.
Now, currently the Java wrapper are manually written, and I like to automatize this. I've found jnaerator that can do that, but I don't know how I should use it in sbt.
I see two general approaches:
use command line, such as java -jar jnaerator ... but I don't know how to setup such command line task in sbt? Also, I would need to know the typical project structure to follow: where to output the jna generated code?
Use jnaerator maven plugin through sbt, if it is possible?
This might take some iteration until we get it do what you need.
For the first approach, here is how you can run custom system command on sbt (you essentially solve this using Scala code). Add the following to your build.sbt file:
lazy val runJnaerator= taskKey[Unit]("This task generates libraries from native code")
runJnaerator := {
import sys.process._
Seq("java" , "-jar", "jnaerator", "..." ).!
}
To execute:
>sbt runJnaerator
Now the question is where do you need these files files to go? Finally, how do you want to invoke everything?

Can I run a subset of pure Java code from an Android project via a regular Java main method?

I have some code in an Android project that parses HTML using Jsoup. It doesn't use anything Android specific, they're just static methods that take an InputStream, and return my model classes. The app uses Gradle to build itself in Android Studio.
Is there any way I can create a standard Java main method to do something like load HTML from a local file, run it through my parser, and output a JSON file (using Gson on my model class)? I'm thinking maybe I can add a new sourceSet to Gradle like a jvmCompatible set of classes? I would greatly prefer not to copy my code to a separate project.
EDIT:
I guess I didn't make this clear, but I would like the be able to run this locally on my dev machine from the command line, rather than on an Android device or emulator.
You don't necessarily need to do anything in the build file to set this up; the build file generates Java .class files, and you can feed them to Java directly from the command line. You can add a main method to any class:
package com.example.foo;
class MyClass {
...
public static void main(String [] args) {
...
}
}
The main method will be happily ignored util you invoke it via the Java command line. You can do this by setting your classpath to the intermediate build directory and telling the Java command line which class to start:
java -classpath app/build/intermediates/classes/debug/ com.example.foo.MyClass
where you pass in the path to the build/intermediates/classes/debug directory in your app module's build output, and the fully-qualified name of the class.
Note that if you're running a release build that uses ProGuard, this main method could get stripped out if it's not otherwise referenced in the code.
Make sure you don't access any Android classes or you'll get a runtime error.
As an aside, you might find it worthwhile to separate out your Java-only code into a Java-only module in the build. Among other things, it would let you use JUnit to write nice test cases for the classes within; if you're asking this question because you want to do some testing of your parser, you might find it convenient to do so within the auspices of a unit test.

Is there any maven plugin allowing to generate a file listing implementations of an interface?

I would like, before packaging phase, to obtain a list of classes implementing a given interface (for this file to be added in output jar). How can I do that ?
The javadoc method would probably work. Another option would be to write an ant script to do it. You can use the maven any plugin to help accomplish this:
http://maven.apache.org/plugins/maven-antrun-plugin/
Well, since I've already implemented that a few times, I now have a ready to use method.
Add the GMaven Plus plugin to your build
Declare an execution using project classpath
in this execution, add the reflections Java library
In your groovy script, find the interface ou want implementations of
Report classes implementing that interface the way you want.

Categories