Running a Java 11.02 JavaFX .jar application produces strange output - intellij-idea

I've been trying to create and run a .jar file that I can run my JavaFX application on any computer running the Java runtime enviroment.
For Java i'm running sdk version 11.02 and for JavaFX i'm running the 11.02 jdk. My IDE is IntellJ IDEA. I've made sure that my Windows enviroment variables have been set up correctly like so:
JAVA_HOME: C:\Program Files\Java\jdk-11.0.2
And in the Path System variables:
c:\program files\java\jdk-11.0.2\bin
c:\program files\javafx-sdk-11.0.2\lib
In Intellj IDEA I've made sure the Path variables have been set like so:
I've also made sure that my project is using the right Java version and that the javafx libraries are being used:
I've also made sure that VM options in the Application runner has the correct command:
With this I can run my JavaFX program with no problems through the IDE's built in Application runner. But this is not the case If I try to create a jar file and run that. I tried following a guide to the first answer of this question, namely the part where he talks about a FAT Jar.
I created a Launcher class as he suggested, with the only difference with mine being that I needed to add a throw exception clause else I got an unhandled exception error on the .main part.
package main;
import com.sun.tools.javac.Main;
public class Launcher {
public static void main(String[] args) throws Exception {
Main.main(args);
}
}
And here is my original JavaFX entry point:
public class Main extends Application
{
private ArmyBuilderRootPane view;
#Override
public void init()
{
Army model = new Army();
view = new ArmyBuilderRootPane();
new ArmyBuilderController(view, model);
}
#Override
public void start(Stage stage)
{
stage.setTitle("Space Marine Army Builder");
stage.setScene(new Scene(view));
stage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
I then follow how he creates a .jar file by first setting up the Artifacts in the project structure, and then finally building it. When I try to run this .jar in both the internal IDE and using the command: java -jar SpaceMarineArmyBuilder.jar within an external Windows command line: I get the following output:
"C:\Program Files\Java\jdk-11.0.2\bin\java.exe" --module-path "C:/Program Files/javafx-sdk-11.0.2/lib" --add-modules javafx.controls,javafx.fxml -Dfile.encoding=windows-1252 -jar "D:\Projects\Code\Space Marine Army Builder (7th Edition)\classes\artifacts\SpaceMarineArmyBuilder_jar\SpaceMarineArmyBuilder.jar"
Usage: javac <options> <source files>
where possible options include:
#<filename> Read options and filenames from file
-Akey[=value] Options to pass to annotation processors
--add-modules <module>(,<module>)*
Root modules to resolve in addition to the initial modules, or all modules
on the module path if <module> is ALL-MODULE-PATH.
--boot-class-path <path>, -bootclasspath <path>
Override location of bootstrap class files
--class-path <path>, -classpath <path>, -cp <path>
Specify where to find user class files and annotation processors
-d <directory> Specify where to place generated class files
-deprecation
Output source locations where deprecated APIs are used
--enable-preview
Enable preview language features. To be used in conjunction with either -source or --release.
-encoding <encoding> Specify character encoding used by source files
-endorseddirs <dirs> Override location of endorsed standards path
-extdirs <dirs> Override location of installed extensions
-g Generate all debugging info
-g:{lines,vars,source} Generate only some debugging info
-g:none Generate no debugging info
-h <directory>
Specify where to place generated native header files
--help, -help, -? Print this help message
--help-extra, -X Print help on extra options
-implicit:{none,class}
Specify whether or not to generate class files for implicitly referenced files
-J<flag> Pass <flag> directly to the runtime system
--limit-modules <module>(,<module>)*
Limit the universe of observable modules
--module <module-name>, -m <module-name>
Compile only the specified module, check timestamps
--module-path <path>, -p <path>
Specify where to find application modules
--module-source-path <module-source-path>
Specify where to find input source files for multiple modules
--module-version <version>
Specify version of modules that are being compiled
-nowarn Generate no warnings
-parameters
Generate metadata for reflection on method parameters
-proc:{none,only}
Control whether annotation processing and/or compilation is done.
-processor <class1>[,<class2>,<class3>...]
Names of the annotation processors to run; bypasses default discovery process
--processor-module-path <path>
Specify a module path where to find annotation processors
--processor-path <path>, -processorpath <path>
Specify where to find annotation processors
-profile <profile>
Check that API used is available in the specified profile
--release <release>
Compile for a specific VM version. Supported targets: 6, 7, 8, 9, 10, 11
-s <directory> Specify where to place generated source files
-source <release>
Provide source compatibility with specified release
--source-path <path>, -sourcepath <path>
Specify where to find input source files
--system <jdk>|none Override location of system modules
-target <release> Generate class files for specific VM version
--upgrade-module-path <path>
Override location of upgradeable modules
-verbose Output messages about what the compiler is doing
--version, -version Version information
-Werror Terminate compilation if warnings occur
Process finished with exit code 2
I have no idea why it's producing this output. It should be running my JavaFX application.
If anybody could help me i'd appreciate it.
Thanks.

Related

How to switch from shared library to static library with CMake

Context:
I built an a.out on my local system with a modern CMake project adding a dependency to a shared library:
find_package(GDAL QUIET)
if(GDAL_FOUND)
get_property(_loc TARGET GDAL::GDAL PROPERTY LOCATION)
message(STATUS "Found GDAL: ${_loc} (version ${GDAL_VERSION})")
add_library(gdal_external INTERFACE) # dummy
Everything works fine on my system. Now I want to distribute the a.out to systems that don't have the dependency (the .so).
Problem:
I copied the binary a.out on a cluster, and when I execute it, I get the following error: error while loading shared libraries: libgdal.so.26: cannot open shared object file: No such file or directory.
Possible solution and other considerations
Installing the dependencies on the cluster, but I don't have admin rights on this server
even if I had the dependency installed by the staff, the same problem will arise later when I will ship the binary to possible users
I can't ask future users to manage dependencies and build from sources.
It seems to me that I should embed all the dependencies in the same executable, that is using a static library rather than share
Executable size or memory issues are not the priority
How do I indicate CMake to use the static version of a library ?

Yocto / OE : recipe with CMake install a shared library .so

I need to figure out how to manage a recipe for a package based on CMake creating a very simple shared library.
The goal is to provide the .so library into the Yocto build system in an atomic way, so can be used by other recipes managing application level.
This is the simple cpp code
#include <iostream>
#include "Student.h"
using namespace std;
Student::Student(string name):name(name){}
void Student::display(){
cout << "A student with name " << this->name << endl;
}
This is kind of CMakeList.txt
cmake_minimum_required(VERSION 2.8.9)
project(directory_test)
set(CMAKE_BUILD_TYPE Release)
#Bring the headers, such as Student.h into the project
include_directories(include)
#However, the file(GLOB...) allows for wildcard additions:
file(GLOB SOURCES "*.cpp")
#Generate the shared library from the sources
add_library(testStudent SHARED ${SOURCES})
#Set the location for library installation
install(TARGETS testStudent DESTINATION lib)
install(FILES student.h DESTINATION include)
This is the recipe studentlib_0.1.bb
SUMMARY = "Cmake application - creates a library"
SECTION = "examples"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "\
file://CMakeLists.txt \
file://student.cpp \
file://student.h \
"
S = "${WORKDIR}"
inherit cmake
EXTRA_OECMAKE = ""
The problem is when I build the specific recipe studentlib
$ bitbake studentlib
...
Build Configuration:
BB_VERSION = "1.38.0"
BUILD_SYS = "x86_64-linux"
NATIVELSBSTRING = "universal"
TARGET_SYS = "arm-poky-linux-gnueabi"
MACHINE = "qemuarm"
DISTRO = "poky"
DISTRO_VERSION = "2.5.2"
TUNE_FEATURES = "arm armv5 thumb dsp"
TARGET_FPU = "soft"
...
NOTE: Executing RunQueue Tasks
ERROR: studentlib-0.1-r0 do_package_qa: QA Issue: -dev package contains non-symlink .so: studentlib-dev path '/work/armv5e-poky-linux-gnueabi/studentlib/0.1-r0/packages-split/studentlib-dev/usr/lib/libtestStudent.so' [dev-elf]
ERROR: studentlib-0.1-r0 do_package_qa: QA run found fatal errors. Please consider fixing them.
ERROR: studentlib-0.1-r0 do_package_qa: Function failed: do_package_qa
ERROR: Logfile of failure stored in: /home/me/yocto-qemuarm-sumo/poky/build/tmp/work/armv5e-poky-linux-gnueabi/studentlib/0.1-r0/temp/log.do_package_qa.21681
ERROR: Task (/home/me/yocto-qemuarm-sumo/poky/meta-me/recipes-cmake/studentlib/studentlib_0.1.bb:do_package_qa) failed with exit code '1'
How can I solve this Issue?
I can't find any example for explanation.
Thanks
In Yocto, files (which are installed in ${D} either manually in do_install or by the make, cmake, autotools, etc... in e.g. do_compile) are put in a package when they match one of the regular expression (or glob, not entirely sure about that) contained in FILES_foo.
One recipe can (and usually does) provide multiple packages. So you'd have multiple FILES_foo1 with their own paths to match.
In Yocto, the file is put in the first package where one of the paths in its FILE_foo matches the file. Even if the file matches the paths of other packages, it'll ever be in only one package, the first one.
FWIW, packages are created from leftmost to rightmost in PACKAGES variable in the recipe. By default, the PACKAGES variable is ${PN}-src ${PN}-dbg ${PN}-staticdev ${PN}-dev ${PN}-doc ${PN}-locale ${PACKAGE_BEFORE_PN} ${PN} (c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n292).
The default FILES_* variables are defined in bitbake.conf as well, c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf. Look for everything starting with FILES_.
In there, you can see that by default, FILES_${PN} has ${libdir}/lib*${SOLIBS} (c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n296) packaged. SOLIBS is, by default, .so.* (c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n280), which means only dot versions of libraries are packaged in the ${PN} package (if they are not matched by another package before). FILES_${PN}-dev on the other hand packages ${FILES_SOLIBSDEV} which defaults to ${base_libdir}/lib*${SOLIBSDEV} ${libdir}/lib*${SOLIBSDEV}, with SOLIBSDEV in turns defaults to .so (c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n313, http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n314 and http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n283). Please note that library filenames should all start with lib to be able to be matched by the default FILES_*.
TL;DR: By default, lib*.so.* in FILES_${PN} and lib*.so in FILES_${PN}-dev.
That's the background needed to understand what is expected in which package. The issue is that -dev package should only contain lib*.so symlinks to versioned libraries (i.e. lib*.so.*).
People usually expect versioned libraries so it's easy to know which version is installed and against which version a particular software should be linked against. If the version does not matter or if the major version only matters, those will then link to the unversioned or major versioned symlinks to the versioned library.
Best practice dictates that behavior.
Two possible cases, either you only provide the unversioned library in which case the solution is to version your library in your cmake or in your recipe. Then everything works out of the box.
Or you have a copy of your versioned library named as an unversioned library, in which case you should delete your copy and just make a symlink to the versioned library.
If that is not an option (but please really consider it), you can try to find a way so that ${PN}-dev does not have this library.
There are multiple options: add lib*.so to FILES_${PN} and either remove the ${PN}-dev from the PACKAGES, remove lib*.so from FILES_${PN}-dev, unset FILES_${PN}-dev, ...

"a bin target must be available for 'cargo run'"

While building a new Rust "Project from other sources", in Intellij IDEA 2017, I was unable to run the project through its UI.
C:/Users/sjsui/.cargo/bin/cargo.exe run error: a bin target must be
available for cargo run
Process finished with exit code 101
I noticed that no --bin target was provided by my build configuration so I placed the path to the projects target folder; same result.
C:/Users/sjsui/.cargo/bin/cargo.exe run --bin C:\Users\sjsui\exercism\rust\hello-world\target\debug
error: no bin target named C:\Users\sjsui\exercism\rust\hello-world\target\debug
I tried creating a fresh Rust project through the Cargo command line interface, and received this error when running it:
error: could not exec the linker link.exe: The system cannot find the file specified. (os error 2)
note: the msvc targets depend on the msvc linker but link.exe was
not found
note: please ensure that VS 2013 or VS 2015 was installed with the
Visual C++ option
Evidently I must install Visual C++ build tools 2017 and am in the process of doing so. Are these errors related, or different issues?
By default, Cargo will consider the file src/main.rs to be the main binary target for the package. If this file doesn't exist, and there are no other binary targets defined in Cargo.toml, you'll get this error.
According to the documentation, when you create a Rust project in IntelliJ IDEA, you get an option to Use a binary (application) template. This should give you a src/main.rs instead of a src/lib.rs (which is the default root file for a library target). Using Cargo on the command line, you can also create an application package with cargo new hello.
Cargo defaults to --bin to make a binary program. To make a library, we'd pass --lib.
When you use --bin on the cargo run command, the argument refers to one of the [[bin]] sections in Cargo.toml, or files following the pattern src/bin/*.rs (the argument replaces the *) if there are no [[bin]] sections in Cargo.toml. For example, cargo run --bin foo will either compile and run src/bin/foo.rs or the [[bin]] section with name = "foo" in Cargo.toml.

Encapsulating a JNI library inside a jar file

I am trying to develop a plugin for Fiji/ImageJ that relies on a native library (JNI).
The JNI library itself depends on libtiff and fftw. On OSX and Linux, I use the class NativeUtils and everything works fine.
On windows, I included binary versions of libtiff and fftw in the CMake package and managed to link the JNI library against those (either statically of dynamically). However, the resulting JNI module does not include libtiff or fftw and I obtain an error when I try to load the JNI library with NativeUtils.loadLibraryFromJar. This is also the case when I include the dependent .dll in the .jar since they are not extracted by NativeUtils.
Here are the relevant lines in CMakeLists.txt:
add_library(fftw STATIC IMPORTED GLOBAL)
set_target_properties(fftw PROPERTIES IMPORTED_LOCATION "${libdir}/libfftw3f-3.lib"
INTERFACE_INCLUDE_DIRECTORIES "${incdir}")
SWIG_ADD_LIBRARY(javainterf
TYPE MODULE
LANGUAGE java
SOURCES javainterf.i javainterf.c src1.c)
SWIG_LINK_LIBRARIES(javainterf libcode1 fftw)
add_jar(Foo
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/java/foo1.java
INCLUDE_JARS java/resources/ij-1.51p.jar
VERSION ${JAR_VERSION})
add_dependencies(Foo javainterf)
add_custom_command(TARGET Foo POST_BUILD
COMMAND "${Java_JAR_EXECUTABLE}" -uf Foo-${JAR_VERSION}.jar
-C ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} ${JNI_LIB_NAME})
How would you make sure that all the dependencies are properly included in the jar and loaded?
You can't load library from inside JAR without extracting it in a first place.
Take a look here at full sample where native code is embedded inside JAR and extracted when needed.
https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo031
Update
Well, in that case, when you need to pack more libs and you want to properly resolve locations, you need to play with runtime env a little bit.
Take a look here:
https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo035
git clone https://github.com/mkowsiak/jnicookbook
cd jnicookbook/recipes/recipeNo035
make
make test
Have fun with JNI!

How to run Kotlin class from the command line?

I understand this question has been asked before, but none of the information there has helped me.
Here is my situation: I can't run a compiled Kotlin class. When I try to run it like I would a normal java class I get the following:
C:\Users\User\Desktop>java _DefaultPackage
Exception in thread "main" java.lang.NoClassDefFoundError: jet/runtime/Intrinsics
at _DefaultPackage.main(Finder.kt)
Caused by: java.lang.ClassNotFoundException: jet.runtime.Intrinsics
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
... 1 more
This led me to believe that the Kotlin runtime was simply missing, given that output. So I tried the following:
C:\Users\User\Desktop>java -cp kotlin-runtime.jar _DefaultPackage
Error: Could not find or load main class _DefaultPackage
Which made me think that maybe I needed to add the class file to my declared classpath so:
C:\Users\User\Desktop>java -cp kotlin-runtime.jar';_DefaultPackage.class _DefaultPackage
Error: Could not find or load main class _DefaultPackage
What am I missing?
Knowing the Name of Your Main Class
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
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. You can change the name of this class within the file by adding this file-targeted annotation:
#file:JvmName("Foo")
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
class MyApp {
companion object {
#JvmStatic fun main(args: Array<String>) {
...
}
}
}
Now 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-stdlib.jar (the standard library)
kotlin-reflect.jar only if using Kotlin reflection
kotlin-test.jar for unit tests that use Kotlin assertion classes
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-stdlib.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-stdlib.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 stdlib 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
You can compile using kotlinc as follows:
$ kotlinc hello.kt -include-runtime -d hello.jar
and then you can run jar file as follows:
$ java -jar hello.jar
I struggled with this for a while as well. You're close, you just need to include your jar in the classpath and pass the qualified name of your "main" class as the primary argument to java.
There are a couple of ways to run Kotlin from the command line, depending on whether you're using the Java bytecode compiler (kotlinc) or the native compiler (kotlinc-native).
If you get an error message about -include-runtime, read the message carefully. You may be using the Kotlin native compiler instead of the Kotlin bytecode compiler. If you want to use the native compiler, see the second section below.
kotlinc (Java bytecode)
It's important to consider that you may not be in the same folder as your main.kt when you try to run your project, and it's not always clear how to tell Kotlin (or Java) to find it.
Assuming that:
You're trying to compile and run from a Windows command prompt.
You have this project structure (after IntelliJ Idea sets up a command-line Kotlin project):
MyNiftyProject
src
main
kotlin
main.kt
You're in the project root.
And you have this main.kt file:
fun main(args: Array<String>) {
println("Hello World!")
}
Compile like this:
kotlinc src/main/kotlin/main.kt -include-runtime -d MyNiftyProject.jar
This puts MyNiftyProject.jar in the root of your project.
Then run like this using the java command-line tool:
java -jar MyNiftyProject.jar
Or run like this using the kotlin command-line tool:
kotlin -classpath MyNiftyProject.jar MainKt
kotlinc-native
For native code, the process is somewhat simpler. Using the same setup as above:
kotlinc-native src/main/kotlin/main.kt -o MyNiftyProject
This puts MyNiftyProject.exe in the root of your project.
Then you just run it as a normal Windows executable:
MyNiftyProject.exe
if you are using a jar file that is generated from IntellijeIdead, you should run the kotlin file like java files but consider that kotlin file name will be something like that :
your file: test.kt
your output in the jar: testKt
java -cp file.jar yourPackage.testKt