I have a default Libgdx Gradle setup, and I need to add my simple text rendering library to it. It consists of a .jar file and native lib file.
This line of build.gradle script seems to work as I would expect, and what it does is add jfreetype.jar java library to my build path.
compile files('../local_lib/jfreetype.jar')
Is there a magic command like this to add native library (.dll to be exact) that is available on my file system and is not Mavenized?
natives "../local_lib/jfreetype32.dll"
This line of code just gives me an error saying that something cannot be found at some repo. I guess there should be a magical line like with .jar file to add native files that are available only on my file system and not on some repo.
The Gradle Natives plugin should do what you want.
You can specify a configuration that points at jar files that contain native dll/so. A gradle task "unpackNatives" will then unpack the dll/so into the build dirs.
Depending upon how you launch your application, you may still need to tell the Java runtime where to find the dll/so. There is some info about how this works at the project website:
https://github.com/cjstehno/gradle-natives
You can add a flat directory as a repository in this way, as mentioned in the dependency-management section in the Gradle User Guide.
repositories {
flatDir {
dirs '../local_lib'
}
}
If you want to create your own dependency-configuration natives, create it like this (more info on the same page):
configurations {
natives
}
Hope that helps.
Related
So, I've recently (partially) completed a Java project with Gradle. Importantly, the project uses absolute pathing to access files in my resources folder, since those files will change after the JAR is made. When I use Eclipse's "export as runnable JAR" functionality, I get something that works perfectly - putting the .jar file in my main directory lets it find everything. However, using Gradle's build function doesn't, because Gradle adds extra layers between the .jar and the resources. To demonstrate, here's my "normal" directory:
./program root directory
|_program.jar
|_resources
|_[actual resources]
And here's the directory Gradle makes:
./build folder
|_libs
| |_program.jar
|_resources
|_main
|_[actual resources]
What I want from Gradle is:
./build folder
|_program.jar
|_resources
|_[actual resources]
Yes, I could manually move the resources and program.jar around in the directory to achieve this, but that feels wrong - this is exactly what Gradle is supposed to do for me, right? I know there has to be SOME way to do it. I just don't know how. So that's why I'm asking for help - how do I do this?
To change the output of resources:
sourceSets.main.output.resourcesDir = "$buildDir/resources"
To change where the JAR file is put:
jar {
// use destinationDir for Gradle < 5.1
destinationDirectory = buildDir
}
If all your resources are meant to be external you may want to exclude them from the JAR file:
jar {
include '**/*.class'
destinationDirectory = buildDir
}
That will only include .class files from the jar task's input. You can customize this using the include and exclude options.
In Gradle 3.x I was able to get some xml mapping files to copy into the classes directory prior to build/jar via the following block:
copy{
from 'src/main/java/com/company/mapping'
into 'build/classes/main/java/com/company/mapping'
include '**/*.xml'
}
In Gradle 4.9 this has been deprecated in favor of:
task copyMappings(type: Copy){
from 'src/main/java/com/company/mapping'
into 'build/classes/main/java/com/company/mapping'
include '**/*.xml'
}
The copyMappings task succeeds, but build/jar does not wait for copyMappings to finish. I have tried variations on build.dependsOn and doFirst{ copyMappings } doLast{ build } but nothing seems to get me the desired effect of having the copied files in place in the 'into' path prior to jar.
This is for Windows 10.
This works for me with Gradle 4.9 on Mac OS:
apply plugin: 'java'
task copyMappings(type: Copy) {
from 'src/main/java/com/company/mapping'
into 'build/classes/main/java/com/company/mapping'
include '**/*.xml'
}
jar.dependsOn copyMappings
jar.doFirst {
assert new File("${projectDir}/build/classes/main/java/com/company/mapping/abc.xml").exists()
assert new File("${projectDir}/build/classes/main/java/com/company/mapping/def.xml").exists()
}
command line is gradle clean jar
I like to model things around source sets where appropriate as doing so let's the build work more reliably with a wide range of plugins and use cases. For example, imagine you want to run an application direct from its class files and resources rather than packaging it as a JAR first. You could make sure that the "run" task depends on the copy as well, but you'd have to do that for every instance where this is a requirement.
Source sets are the ideal solution because they have the concept of a runtime classpath, which will work for packaging, instrumentation, running, testing and so on.
With that in mind, I would go for this simple declaration and get rid of the copy task:
sourceSets {
main {
resources {
srcDir "src/main/java"
include "**/*.xml"
}
}
}
The XML files will end up in a different directory from your current approach, but that shouldn't matter unless you have tasks that assume the location rather than using the source set model to get the necessary information.
Note The above include directive applies to all the resources in src/main/resources as well. So if you have properties files or text files or anything else in there, they will be excluded. The simplest solution is to add all required resource file patterns to the include directive.
is it possible to use a Android Studio Library (aar file) in a Qt app?
The problem is, that I want to implement a mobile App with Qt, but there is only a library for Android Studio. Is it possible to include the library in the Qt project or have I to write a wrapper class for it?
If I have to implement a wrapper, do I have to use the JNI and are there any examples for using it with C++ and a Java lib?
I found the answer, that worked for me.
First you have to unzip the aar file, so you can get your jar library file.
Then you can follow the instructions in this link to include the library to your apk:
http://doc.qt.io/qt-5/android3rdpartylibs.html
When you have finished this, you have to implement your own Java wrapper class to interact with the library. Therfore you have to use the QAndroidJniObject class from Qt. Here are more information about it.
http://doc.qt.io/qt-5/qandroidjniobject.html
You could also have a look at this example, where they use their own java class. http://doc.qt.io/qt-5/qtandroidextras-notification-example.html
You can add .aar files directly to your project
In gradle file add .aar folder to dependencies
compile project(':myAarFolder1.1')
and include it in gradle.settings
include ':myAarFolder1.1'
the aar file location in my project is like this
android/myAarFolder1.1/.aar
android/myAarFolder1.1/build.gradle
android/myAarFolder1.1/build.gradle file content
configurations.maybeCreate("default")
artifacts.add("default", file('myAarFolder1.1.aar'))
Ok incase anyone else comes across this I figured it out.
If you don't already have an android source folder add one by inserting this into your .pro file
android {
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android-sources
}
Here is an example file structure:
project/android-sources
project/android-sources/settings.gradle
project/android-sources/build.gradle
project/android-sources/LibraryFolder
project/android-sources/LibraryFolder/Library.aar
project/android-sources/LibraryFolder/build.gradle
You might have to get your build.gradle file from ../build-Android/android-build/build.gradle and copy it into project/android-sources/ if it doesn't already exist.
Insert this into your build.gradle file within dependencies { }
api project(':LibraryFolder')
Insert this into your settings.gradle file at the bottom
include ':LibraryFolder'
Create the build.gradle file inside LibraryFolder and insert:
configurations.maybeCreate("default")
artifacts.add("default", file('Library.aar'))
and lastly if the library you are adding has other 3rd party dependencies you will have to add them to project/android-sources/build.gradle
For example I was adding ImagePicker and had to insert the below lines inside dependencies { } but above api project(':LibraryFolder')
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'com.github.bumptech.glide:glide:4.9.0'
from the library's source
I've successfully configured my gradle build script to create a zip distribution of my application with an extra 'config' folder at the root. This folder contains (at least right now) only one properties file in use by the application, and is on the classpath for the application.
What I'm looking for now, however, is a way to do the same with the 'run' task in the application plugin. When I try to run my application this way, (for testing), my program fails to run because of a class trying to access this properties file on the root of the classpath.
A bonus would be if I could get IntelliJ or Eclipse to also add this folder to its classpath just like the other folders (src/main/java, src/main/resources, ...) so I can run and debug my code from within the IDE without invoking a gradle task. I want to try to avoid as much as possible tying this code to any one IDE, so that when anybody needs to work on the project, they just need to import the build.gradle file and have the IDE make the appropriate config files it needs.
Here is my build.gradle file:
apply plugin: 'application'
mainClassName = "MainClass"
startScripts {
// Add config folder to classpath. Using workaround at
// https://discuss.gradle.org/t/classpath-in-application-plugin-is-building-always-relative-to-app-home-lib-directory/2012
classpath += files('src/dist/config')
doLast {
def windowsScriptFile = file getWindowsScript()
def unixScriptFile = file getUnixScript()
windowsScriptFile.text = windowsScriptFile.text.replace('%APP_HOME%\\lib\\config', '%APP_HOME%\\config')
unixScriptFile.text = unixScriptFile.text.replace('$APP_HOME/lib/config', '$APP_HOME/config')
}
}
repositories {
...
}
dependencies {
...
}
Likely what needs to happen is that I need to have the /src/dist/config folder to be copied into the build directory and added to the classpath, or have its contents be copied into a folder that is already on the classpath.
I ended up taking Opal's suggestion as a hint, and came up with the following solution. I added the following to my build.gradle file:
task processConfig(type: Copy) {
from('src/main/config') {
include '**/*'
}
into 'build/config/main'
}
classes {
classes.dependsOn processConfig
}
run {
classpath += files('build/config/main')
}
Alternatively, a simpler approach would be to add a runtime dependency to my project as such:
dependencies {
...
runtime files('src/main/config')
}
I didn't end up doing it this way, however, because my distribution package ended up having .properties files in the lib folder... and I'm just picky that way.
As you can see in the docs run is a task of type JavaExec. So classpath for it can be modified. Try to add config folder to the classpath. See here.
I am new to java programming and I have created a program which integrates selenium, apachepoi and java swing. While compiling the program I was able to compile it successfully and the program does run right; however when I tried making a jar file for my program it shows java.lang.NoClassDefFoundError: org/apache/poi/ss/usermodel/Row error.
Below is my program's folder structure
c:\users\userid\documents\java\crazyrunner
The java file is with name CrazyRunner.java within crazyrunner folder
The program is within a package with name crazyrunner (first line of the program starts with package crazyrunner)
Command used to compile (not sure whether it is relevant)
javac -encoding UTF8 crazyrunner\CrazyRunner.java
Compilation resulted in creation of .class files in both parent (java) and child (crazyrunner) folders
Command used to run
java crazyrunner.CrazyRunner (This worked just fine)
Command used generate the jar
jar cvfm CrazyRunner.jar manifest.mf *.class crazyrunner\*.class
The result of the jar command is successfull and all class files within crazyrunner and outside crazyrunner (within the parent folder 'Java') are added to the jar (CrazyRunner.jar)
The manifest.mf file has data as below
Manifest-Version: 1.0
Created-By: Eric Stanley
Main-Class: crazyrunner.CrazyRunner
Class-Path: "C:\poi-3.10-beta2\poi-3.10-beta2-20130904.jar"
"C:\poi-3.10-beta2\poi-examples-3.10-beta2-20130904.jar"
"C:\poi-3.10-beta2\poi-excelant-3.10-beta2-20130904.jar"
..
Ends with 2 new lines
Not sure about what am I missing :-( and I have spent a whole damn day fixing this and left without choice but to post this q!! and yes I did tried all options that stackoverflow already has and nothing worked out :-(
Option 1:
Open the Control Panel
Go to System
Go to Advanced Systems Properties
Then Environment Variables
In System Variables, click Add
New Variable Name: _JAVA_OPTIONS
New Variable Value: -Xmx512M (tried -Xmx1024M too)
Click OK
Option 2:
Reinstall Java
Option 3:
Open the Run box
Enter msconfig
Services (tab)
CHECK "Hide All Microsoft Services"
Click "Disable All" (button)
Click APPLY
Click OK
Option 4:
Update manifest.txt file with classpath
Help is much appreciated
Note:
The program opens up a GUI (while I enter java crazyrunner.CrazyRunner) and when I tried giving CrazyRunner.jar alone in the command prompt, it throws an error stating Java Virtual Machile Launcher. A java exception occurred
PS:
I am using Windows 8 and the version of java is 1.7.0_51 and I am not using any IDE and I do have a hunch that this might be due to too many jar files in the classpath. If yes, fix for that is badly needed!!
Thanks for all your responses and at last I found the answer. Gradle!! :-)
As I assumed, there was no change to the already created .jar file; meaning the jar file that I created with the manifest file was right and the issue is that the class files that are available during compile time were not available during run time. Hence, I used all the jar files that were used for compilation and also my already created jar file (CrazyRunner.jar) to build my new jar file using gradle.
Steps followed:
Downloaded gradle 1.10 from http://downloads.gradle.org/distributions/gradle-1.10-all.zip
Extracted the files under "C:\gradle-1.10
Opened cmd prompt in administrator mode and typed "C:\Windows\system32\rundll32.exe" sysdm.cpl,EditEnvironmentVariables
Added GRADLE_HOME environment variable with value as C:\gradle-1.10\bin (under system variables section)
Added %GRADLE_HOME% to the PATH variable (under system variables section)
Added JAVA_OPTS environment variable with value -Xms256m -Xmx2048m
Created a new file with name build.gradle into the project folder (crazyrunner)
Wrote the below code in build.gradle file
apply plugin: 'java'
sourceCompatibility = 1.6
targetCompatibility = 1.8
defaultTasks = ['clean', 'jar']
dependencies {
compile fileTree(dir: 'corelib', includes: ['*.jar'])
compile fileTree(dir: 'libs', includes: ['*.jar'])
}
jar {
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
manifest { attributes 'Main-Class': 'CrazyRunner' }
}
Copied all jar files (just searched by .jar) from C:\poi-3.10-beta2 and C:\selenium-2.39.0 and pasted into a separate folder (named libs) within my project folder (within crazyrunner)
Copied my already created jar(CrazyRunner.jar that was created as mentioned in the original question) file into a separate folder (named corelib) within my project folder (within crazyrunner)
Note: At this point, my project folder (crazyrunner) had 2 sub-folders (libs and corelibs) and 1 file (build.gradle)
Opened command prompt (normal mode) and traversed to the project folder (crazyrunner)
Typed command gradle build
Thatz it!!
It took around 20 mins for me to complete the build successfully and after a long night search I found it working!!
My Learning:
Gradle basically integrates all the compiled files within the jar (if built as above, like the build.gradle file), so that the newly created jar file doesn't need any extra dependencies during runtime which is an advantage; however, since all dependent files are added to the jar, it makes the size huge but the file runs in any system even without selenium and apache-poi (I hope ;-))
Thanks y'all and my special thanks to jbaliuka :-) Nice work guys!!
A few things that you could check is the manifest file whether it has follow the correct format as in:
http://docs.oracle.com/javase/tutorial/deployment/jar/downman.html
Note that the classpath uses slash / instead of backslash \, and multiple jar files are concatenated by a space character, NOT by a newline.
E.g. something like following would be a valid manifest file:
Manifest-Version: 1.0
Created-By: Eric Stanley
Main-Class: crazyrunner.CrazyRunner
Class-Path: "C:/poi-3.10-beta2/poi-3.10-beta2-20130904.jar" "C:/poi-3.10-beta2/poi-examples-3.10-beta2-20130904.jar" "C:/poi-3.10-beta2/poi-excelant-3.10-beta2-20130904.jar"
And also make sure that the jar files location are correctly spelled up to their lower and upper case.