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
}
Related
Seems like project(:some-other-project).sourceSets.output.classesDir is deprecated since sourceSets isn't available as an option for project(). Is there another way to get the classesDir output directory from another project?
I know there are a lot of questions that seem similar. I have also spent a few hours getting to grips with Gradle multiprojects. But I still don't understand what the best course of action is here. Incidentally I am using Groovy as my coding language, but explanations referencing Java would be just as good.
I have developed an Eclipse Gradle project, "ProjectA", which in particular has a class, IndexManager, which is responsible for creating and opening and querying Lucene indices.
Now I am developing a new Eclipse Gradle project, "ProjectB", which would like to use the IndexManager class from ProjectA.
This doesn't really mean that I would like both projects to be part of a multiproject. I don't want to compile the latest version of ProjectA each time I compile ProjectB - instead I would like ProjectB to be dependent on a specific version of ProjectA's IndexManager. With the option of upgrading to a new version at some future point. I.e. much as with the sorts of dependencies you get from Maven or JCenter...
Both projects have the application plugin, so ProjectA produces an executable .jar file whose name incorporates the version. But currently this contains only the .class files, the resource files, and a file called MANIFEST.MF containing the line "Manifest-Version: 1.0". Obviously it doesn't contain any of the dependencies (e.g. Lucene jar files) needed by the .class files.
The application plugin also lets you produce a runnable distribution: this consists of an executable file (2 in fact, one for *nix/Cygwin, one for Windows), but also all the .jar dependencies needed to run it.
Could someone explain how I might accomplish the task of packaging up this class, IndexManager (or alternatively all the classes in ProjectA possibly), and then including it in my dependencies clause of ProjectB's build.gradle... and then using it in a given file (Groovy or Java) of ProjectB?
Or point to some tutorial about the best course of action?
One possible answer to this which I seem to have found, but find a bit unsatisfactory, appears to be to take the class which is to be used by multiple projects, here IndexManager, and put it in a Gradle project which is specifically designed to be a Groovy library. To this end, you can kick it off by creating the project directory and then:
$ gradle init --type groovy-library
... possible to do from the Cygwin prompt, but not from within Eclipse as far as I know. So you then have to import it into Eclipse. build.gradle in this library project then has to include the dependencies needed by IndexManager, in this case:
compile 'org.apache.lucene:lucene-analyzers-common:6.+'
compile 'org.apache.lucene:lucene-queryparser:6.+'
compile 'org.apache.lucene:lucene-highlighter:6.+'
compile 'commons-io:commons-io:2.6'
compile 'org.apache.poi:poi-ooxml:4.0.0'
compile 'ch.qos.logback:logback-classic:1.2.1'
After this, I ran gradle jar to create the .jar which contains this IndexManager class, initially without any fancy stuff in the manifest (e.g. name, version). And I put this .jar file in a dedicated local directory.
Then I created another Gradle project to use this .jar file, the critical dependency here being
compile files('D:/My Documents/software projects/misc/localJars/XGradleLibExp.jar' )
The file to use this class looks like this:
package core
import XGradleLibExp.IndexManager
class Test {
public static void main( args ) {
println "hello xxx"
Printer printer = new Printer()
IndexManager im = new IndexManager( printer )
def result = im.makeIndexFromDbaseTable()
println "call result $result"
}
}
class Printer {
def outPS = new PrintStream(System.out, true, 'UTF-8' )
}
... I had designed IndexManager to use an auxiliary class, which had a property outPS. Groovy duck-typing means you just have to supply anything with such a property and hopefully things work.
The above arrangement didn't run: although you can do build and installdist without errors, the attempt to execute the distributed executable fails because the above 6 compile dependency lines are not present in build.gradle of the "consumer" project. When you put them in this "consumer" Gradle project's build.gradle, it works.
No doubt you can add the version to the generated .jar file, and thus keep older versions for use with "consumer" projects. What I don't understand is how you might harness the mechanism which makes the downloading and use of the dependencies needed by the .jar as automatic as we are used to for things obtained from "real repositories".
PS in the course of my struggles today I seem to have found that Gradle's "maven-publish" plugin is not compatible with Gradle 5.+ (which I'm using). This may or may not be relevant: some people have talked of using a "local Maven repository". I have no idea whether this is the answer to my problem... Await input from an über-Gradle-geek... :)
You should be able to update the Eclipse model to reflect this project-to-project dependency. It looks something like this (in ProjectB's build.gradle):
apply plugin: 'eclipse'
eclipse {
classpath.file.whenMerged {
entries << new org.gradle.plugins.ide.eclipse.model.ProjectDependency('/ProjectA')
}
project.file.whenMerged {
// add a project reference, which should show up in /ProjectB/.project's <projects> element
}
}
These changes may be to the running data model, so they may not actually alter the .classpath and .project files. More info can be found here: https://docs.gradle.org/current/dsl/org.gradle.plugins.ide.eclipse.model.EclipseModel.html
This issue is discussed here: http://gradle.1045684.n5.nabble.com/Gradle-s-Eclipse-DSL-and-resolving-dependencies-to-workspace-projects-td4856525.html and a bug was opened but never resolved here: https://issues.gradle.org/browse/GRADLE-1014
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!
I got a problem with my gradle build. I use the standard proposed by the Spring Website (https://spring.io/guides/gs/rest-service/), but when I try to use gradle build, I got this error :
It doesnt work for this gradle, but when I use another one (that I took when I was at school) it work perfectly.
There are two possibilities
Your source directory is not in the right location (use the sourceSets directive to fix this. your source directory should resemble something like src/main/java/your/package)
Add this to indicate where your main class is
springBoot {
mainClass = "hello.FileUploader"
}
I am pretty sure it is 1.
I also have this problem, Here I solved the problem:
use org.springframework.boot:spring-boot-starter instead of org.springframework.boot:spring-boot-starter-web, if your project is only an module that will be used in other project.
Or Set the main class in gradle:
mainClassName = 'your.package.MainClass'
Or Just disable the bootRepackage
bootRepackage {
enabled = false
}
There is no main method in your project (otherwise the plugin would find one). A main method has a very specific signature, so check that you have public static void main(String[] args).
If the main class is not defined in the current project which the build.gradle file belongs to, but you want to launch it for some purpose, like sprint integration test. Do it like this:
Adding
bootRepackage {
mainClass = 'your.app.package.Application'
}
in build.gradle (after the line apply plugin: 'spring-boot', because the plugin needs to be loaded) fix the problem.
I know this is a very old post. But I came across this issue while trying to build my first spring- boot application (https://spring.io/guides/gs/spring-boot/#scratch).
So the location of the pom.xml, mentioned in the tutorial is incorrect. You need to place it outside your src folder.
So here is the final directory structure -
/workspace/src/main/java/hello/HelloController.java
/workspace/src/main/java/hello/Application.java
/workspace/pom.xml
I solved it by specifying the encoding. Probably it's because I wrote the code in an IDE.
java -Dfile.encoding=UTF-8 -jar build <filename>.jar
This happened to me as well.
I was confused by the location of build.gradle file: I thought it should be located in src/main/java/hello, because it is mentioned right after the instruction to create this sub-directory structure.
It should be placed in the root folder containing src folder. Once I did that and called "gradle build" from the root folder and not "./gradlew build" as the guide instructs, build was successful.
I did not perform the standard installation for gradle, just downloaded the binaries, maybe this is the reason that "./gradlew build" failed for me.
I want to add this project as library to my project in android studio.
this is what I tried,
I have my project directory as f:/my project/my app/src
and my library in f:/my project/my library/src
I import the module (the library) by going to file > import module > selecting the library
then I got to file > project structure > modules > dependencies tab > select my project > add module dependency apply ok and then done
however when I use the code from the library I get the usual syntax error (the class ... could not be found)
also I noticed this popup (see image)
I am new to android studio or intelliJ, how do I fix this.
Thanks!
Edit the settings.gradle file (in directory f:/my project), it must contains something like this:
include 'my app','my library'
If this file don't exists: create it manually. The settings.gradle contains the list of gradle modules in a multi-module project.
Then you must add the dependency to your library in app. To do so edit the my app/build.gradle and add this line :
dependencies {
compile project(':my library')
}
I also notice that you don't use default structure for your projects (i.e. you put the code in src/ instead of src/main/java) so you will have to overwrite some values of the default fileSet in the build.gradle of your projects. Be sure to have something like this in my app/build.gradle and my library/build.gradle :
android {
sourceSets {
main {
java.srcDirs = ['src']
}
}
}