i try gradle -d compileJava in my try project, and gradle raise "Skipping task ':compileJava' as it has no source files.". the worse thing is that i can't see anything created in build/. i create this project only with running gradle init and creating a "src/Ex.java".
my question is:
How to load default "compileJava" or define my "compileJava" to fix this warning.
By default, Java source files need to go into src/main/java (or src/test/java for test sources). Either adapt your directory structure accordingly, or reconfigure the source directory as follows:
sourceSets {
main {
java {
srcDirs = ["src"]
}
}
}
You can also change gradle version to 4.8 in
gradle-wrapper.properties
distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-bin.zip
then do:
./gradlew build
Related
I recently wanted to build jars of my JavaFX project with Gradle. So I went ahead and created the wrapper in my project directory and edited my build.gradle file to the below.
apply plugin: 'java'
apply plugin: 'application'
sourceSets.main.java.srcDirs = ['/']
mainClassName = "Main"
task wrapper(type: Wrapper) {
gradleVersion = '4.8'
}
jar {
manifest {
attributes(
'Class-Path': '../',
'Main-Class': 'Main'
)
}
from('/') {
include 'images/**/*.png'
include 'images/**/*.jpg'
include 'styles/css/**/*.css'
include 'fonts/**/*.TTF'
include 'fonts/**/*.ttf'
}
}
Using this, my compiled jar works as intended. No errors. But whenver I run gradlew runI get the following error.
Caused by: java.lang.NullPointerException
at styles.java.TitleStyles.<init>(TitleStyles.java:9)
at scenes.TitleScene.<init>(TitleScene.java:34)
at scenes.SceneController.<clinit>(SceneController.java:6)
... 14 more
The code in question is
private String stylesheet = this.getClass().getResource("/styles/css/TitleStyles.css").toExternalForm();
and my project structure looking like this
Project Structure Picture
Project Structure Picture #2
Any ideas on why I'm unable to do gradlew run?
The reason you are hitting a NullpointerException when you use gradle run is because the folder structure "/styles/...." is not in the classpath
To verify this .. you can ad this line in your Main.java :
System.out.println(System.getProperty("java.class.path")) ;
and run it as both java -jar
and gradle run
and you will see the difference.
Tp solve this , use the standard gradle java folder structure :
src
- main
--- java
--- resources
It was indeed a classpath issue, but there was a few more things I had to do to resolve my problems. I had to recreate my gradle project with the following structure.
src
-main
--java
---projectCodeHere
--resources
---nonJavaFileCodeHere
I had to relocate my non-java code to resources, otherwise it wasn't copied along with the .class files.
And then I had to change my code to look a bit like thisP
private String stylesheet = getClass().getClassLoader().getResource("css/ConnectionStyles.css").toExternalForm();
Everything worked correctly after that. It seems Gradle and IntelliJ are picky about the structure of project, and I couldn't find a "clean" solution to changing classpaths, so I ended up just reorganizing my project and am I ever the happier for it. Thanks for the help!
This is a follow up question for how to execute a built fat JAR as a gradle task?
I don't have enough points to ask my question as a comment. So I have to ask again. This question has been asked in other formats and scenarios multiple times but none of those responses helped me.
My problem:
scenario 1 : create a single jar with dependencies using gradle fatJar
scenario 2 : create a single jar with dependencies using maven assembly
Execute
java -cp sample.jar com.example.ClassA
on jar files generated in both processes.
Issue:
jar from Process 1 gives me
Error : Could not find or load main class com.example.ClassA
jar from Process 2 executes correctly.
I have extracted both jar files and both of them have the same folder structure and same files - meaning the compiled class files are present in both jar files.
I haven't specified any manifest entries in either process because I have multiple main classes and I am not trying to generate an executable jar file.
My build.gradle file looks like below:
apply plugin: 'java'
apply plugin: 'maven'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenLocal()
}
sourceSets {
main{
java{
srcDirs 'src/main/java'
}
}
}
processResources {
from 'src/main/resources'
}
task compile (type: JavaCompile) {
source = sourceSets.main.java.srcDirs
include '**/*.java'
classpath = sourceSets.main.compileClasspath
destinationDir = sourceSets.main.output.classesDir
}
compile.options.compilerArgs = ["-sourcepath", "$projectDir/src/main/java"]
dependencies {
.
.
.
}
task fatJar(type:Jar) {
baseName = 'xxxxxxx'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
defaultTasks 'clean', 'compile', 'fatJar'
EDIT - 1:
I have tried relative path to the jar, absolute path to the jar and even browsing to the folder which contains the jar. No luck whatsoever.
I have tried using '/' instead of '.' in the package name. No luck there either.
I have tried using java VM arguments providing huge enough heap space. Nada.
Tried executing on powershell. Got the below error:
+ CategoryInfo : NotSpecified: (Error: Could not lo...ClassA:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
I wanted to see the contents directly so used jar -tvf path_to_jar\sample.jar . Interestingly jar command didn't execute and complained that command was not found on the classpath. I had to browse to the java installation directory and execute the command and it showed the file contents.
I am running out of ideas and options here.
Any pointers?
For some reason, no matter which config I use for fatJar, the final jar gives errors when trying to execute the main class.
Using ShadowJar task I was able to build the necessary jar and execute the main class as specified in the question.
I know this defeats the entire purpose of the question about using fatJar and executing the main class. But due to time-constraints, I had to look for alternatives.
For those who are looking for config for Shadow Jar tasks, I did it using below:
buildscript {
repositories {
mavenLocal()
dependencies {
classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.3'
}
}
}
apply plugin: 'com.github.johnrengelman.shadow'
and finally to execute the task, I used
gradle shadowJar
It looks like your execution command is not valid. After building your project with:
./gradlew clean fatJar
you should use following command to execute your program:
java -cp build/libs/xxxxxxx.jar com.example.ClassA
Parameter -cp build/libs/xxxxxxx.jar sets the classpath for JVM that is about to start and it has to point to the existing JAR file (you can use relative or absolute path to this file).
Take a look at following screencast I've recorded a few minutes ago:
You can see that if I change execution command to:
java -cp xxxxxxx.jar com.example.ClassA
I got exactly the same error as yours:
Error: Could not find or load main class com.example.ClassA
Here you can find a simple Gradle project I used to play around with your build.gradle file example. I've added a single dependency to prove that fatJar builds a JAR with dependencies and I've added to classes with public static void main(String[] args) to prove that you can pick any main class from command line. I hope it helps.
I have a *.jar file in my Gradle / Buildship project that resides in a lib folder. I include it in my build.gradle via:
compile files('libs/local-lib.jar')
I also have a correspondinglocal-lib-sources.jar file that I would like to attach to it. In Eclipse, for manually managed dependencies this works via context menu of build path entry -> Properties -> Java Source Attachment. However, for gradle-managed dependencies, that option is not available.
Does anybody know how what the gradle/buildship way to do this looks like? My dependency is in no repository, so I'm stuck with compile files for now.
If you want to use Buildship with Eclipse then you are out of luck since this is not currently supported by gradle (see https://discuss.gradle.org/t/add-sources-manually-for-a-dependency-which-lacks-of-them/11456/8).
If you are ok with not using Buildship and manually generating the Eclipse dot files you can do something like this in your build.gradle:
apply plugin: 'eclipse'
eclipse.classpath.file {
withXml {
xml ->
def node = xml.asNode()
node.classpathentry.forEach {
if(it.#kind == 'lib') {
def sourcePath = it.#path.replace('.jar', '-sources.jar')
if(file(sourcePath).exists()) {
it.#sourcepath = sourcePath
}
}
}
}
}
You would then run gradle eclipse from the command line and import the project into Eclipse using Import -> "Existing Projects into Workspace"
Another (possibly better) option would be to use a flat file repository like this:
repositories {
flatDir {
dirs 'lib'
}
see https://docs.gradle.org/current/userguide/dependency_management.html#sec:flat_dir_resolver
You would then just include your dependency like any other; in your case:
compile ':local-lib'
This way Buildship will automatically find the -sources.jar files since flatDir acts like a regular repository for the most part.
Use an extra folder called lib or similar on the same directory level as src or you build script.
dependencies {
//local file
compile files('lib/local-lib-sources.jar')
// others local or remote file
}
Right now I have got a Java library which has a test class. In that class I want to access some files located on my hard disk.
The build.gradle looks like this:
apply plugin: 'java'
dependencies {
testCompile 'junit:junit:4.11'
}
My file is under java_lib/src/test/assets/file.xml and the Java class is under java_lib/src/test/java/<package_name>.java
Therefore I execute
final InputStream resourceAsStream = this.getClass().getResourceAsStream("assets/file.xml");
Unfortunately I get null back. What am I doing wrong?
To get thing rolling you need to add the following to the gradle file:
task copyTestResources(type: Copy) {
from "${projectDir}/src/test/resources"
into "${buildDir}/classes/test"
}
processTestResources.dependsOn copyTestResources
What it basically does is copying all the files in the src/test/resource directory to build/classes/test, since this.getClass().getClassLoader().getResourceAsStream(".") points to build/classes/test.
The issue is already known to Google and they want to fix it in Android Studio 1.2 (since they need IntelliJ14 for that and it seems like it will be included in Android Studio 1.2)
Try placing file.xml under src/test/resources and use this.getClass().getResourceAsStream("file.xml") (without the folder prefix)
The problem appears to be that the assets folder is not part of the test runtime classpath, hence this.getClass().getResourceAsStream("assets/file.xml") wouldn't be able to resolve the path as you expected.
By default, the test resources folder in a Gradle java project is src/test/resources (same as a Maven java project). You can override it to assets folder if you wish by adding this in the project's build.gradle file:
sourceSets.test {
resources.srcDirs = ["src/test/assets"]
}
In build.gradle, add this :
sourceSets.test {
resources.srcDirs = ["src/test"]
}
In your code, access your resource like this :
getClass().getClassLoader().getResourceAsStream("assets/file.xml"));
Works for me.
Thanks for pointing out the Google issue I've been looking all day for this...
In "Android Studio 1.1 RC 1" (gradle build tool 1.1.0-rc1) there is no need to add the work around to the gradle file, but your you have to execute the test from the gradle task menu (or command prompt)!
This worked for me (3 years later, gradle 4.10)
subprojects {
junitPlatformTest.dependsOn processTestResources
}
I have a gradle project with multiple packages. After the build, each package generates its jar files in build/libs. The external jar dependencies are pulled into ~/.gradle. I would now like to run the service locally from the commandline with the appropriate classpath. For this purpose, I am writing a script that constructs the classpath. The problem is that the script does not understand all the external dependencies and hence cannot construct the classpath. Is there a way for gradle to help with this? Ideally, I would like to dump all the dependencies into a folder at the end of the build.
Firstly, i would suggest using the application plugin if you can, since it takes care of this already.
If you want to dump the classpath to a file yourself, the simplest way is something like:
task writeClasspath << {
buildDir.mkdirs()
new File(buildDir, "classpath.txt").text = configurations.runtime.asPath + "\n"
}
If you want to actually copy all the libraries on the classpath into a directory, you can do:
task copyDependencies(type: Copy) {
from configurations.runtime
into new File(buildDir, "dependencies")
}
You could try something like this in your build script:
// add an action to the build task that creates a startup shell script
build << {
File script = file('start.sh')
script.withPrintWriter {
it.println '#!/bin/sh'
it.println "java -cp ${getRuntimeClasspath()} com.example.Main \"\$#\""
}
// make it executable
ant.chmod(file: script.absolutePath, perm: 'u+x')
}
String getRuntimeClasspath() {
sourceSets.main.runtimeClasspath.collect { it.absolutePath }.join(':')
}