How do I implement "application run" task in Gradle? - java

I'm using Gradle and I wonder how I can implement a run task so I can run the program from the command "./gradlew run". I have a project named "demo" and it have the task "application run". Then I created the project "HouseObserver" and it have not the task "application run".
My build.gradle file looks like this.
plugins {
// Apply the java-library plugin to add support for Java Library
id 'java-library'
}
repositories {
// Use jcenter for resolving dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
}
apply plugin: 'java'
task runApp(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'HouseObserver.Main'
}
// Using and creating an Executable Jar
jar {
manifest {
attributes('Main-Class': 'HouseObserver.Main')
}
}
task runExecutableJar(type: JavaExec) {
// Executable jars can have only _one_ jar on the classpath.
classpath = files(tasks.jar)
// 'main' does not need to be specified
}
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:28.0-jre'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
// Need at least basic JME
compile "org.jmonkeyengine:jme3-core:3.3.0-beta1"
compile "org.jmonkeyengine:jme3-desktop:3.3.0-beta1"
compile "org.jmonkeyengine:jme3-lwjgl3:3.3.0-beta1"
compile group: 'com.simsilica', name: 'lemur', version: '1.13.0'
compile group: 'com.simsilica', name: 'lemur-proto', version: '1.11.0'
// needed for the style language
runtime "org.codehaus.groovy:groovy-all:2.4.5"
// Standard utility stuff
compile 'com.google.guava:guava:19.0'
compile 'org.slf4j:slf4j-api:1.7.13'
runtime 'org.apache.logging.log4j:log4j-slf4j-impl:2.5'
runtime 'org.apache.logging.log4j:log4j-core:2.5'
}
I'm also trying the way to implement a task from a plugin.
plugins {
id 'application'
}
application {
mainClassName = 'my.packages.to.the.Main'
}
But nothing happens. Why?
EDIT:
Here is my latest gradle file.
plugins {
// Apply the java-library plugin to add support for Java Library
id 'java-library'
id 'application'
}
application {
mainClassName = 'HouseObserver.Main'
}
repositories {
// Use jcenter for resolving dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
}
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:28.0-jre'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
// Need at least basic JME
compile "org.jmonkeyengine:jme3-core:3.3.0-beta1"
compile "org.jmonkeyengine:jme3-desktop:3.3.0-beta1"
compile "org.jmonkeyengine:jme3-lwjgl3:3.3.0-beta1"
compile group: 'com.simsilica', name: 'lemur', version: '1.13.0'
compile group: 'com.simsilica', name: 'lemur-proto', version: '1.11.0'
// needed for the style language
runtime "org.codehaus.groovy:groovy-all:2.4.5"
// Standard utility stuff
compile 'com.google.guava:guava:19.0'
compile 'org.slf4j:slf4j-api:1.7.13'
runtime 'org.apache.logging.log4j:log4j-slf4j-impl:2.5'
runtime 'org.apache.logging.log4j:log4j-core:2.5'
}

Related

VSCode Java extension gives error "Cannot find the class file for javax.servlet.http.HttpServletResponse."

I have a java project using gradle as my build system. I am developing in VSCode using the Java extension by Redhat. I am developing on Ubuntu 20.04 with openjdk 11.
When I build the project from the command line using './gradlew assemble', I don't get any build error.
But when I open the project in vscode, I get the following problem in the problems view...
The project was not built since its build path is incomplete. Cannot find the class file for javax.servlet.http.HttpServletResponse. Fix the build path then try building this project
and...
The type javax.servlet.http.HttpServletResponse cannot be resolved. It is indirectly referenced from required .class files
My build.gradle is as follows....
plugins {
id 'com.google.cloud.tools.jib' version '2.4.0'
}
apply plugin: 'java'
// Use maven repository
repositories {
mavenCentral()
google()
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'org.eclipse.jetty:jetty-servlet:9.4.19.v20190610'
implementation 'org.eclipse.jetty:jetty-client:9.4.19.v20190610'
implementation group: 'org.eclipse.jetty', name: 'jetty-util', version: '9.4.29.v20200521'
implementation 'mysql:mysql-connector-java:8.0.16'
implementation 'com.google.cloud.sql:mysql-socket-factory-connector-j-8:1.0.16'
implementation 'org.apache.commons:commons-dbcp2:2.7.0'
implementation 'org.jdbi:jdbi3-core:3.10.1'
implementation 'com.google.firebase:firebase-admin:6.11.0'
implementation 'com.google.apis:google-api-services-oauth2:v1-rev155-1.25.0'
implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.0.1'
implementation group: 'org.reflections', name: 'reflections', version: '0.9.12'
implementation 'com.github.bhlangonijr:chesslib:1.2.3'
// compile project('chesslib')
//runtime files('../../chesslib/build/libs/chesslib-1.1.12.jar')
}
task runServer(type: JavaExec) {
enableAssertions = true
classpath = sourceSets.main.runtimeClasspath
main = 'ChessServer'
}
task runClient(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'ChessClient'
standardInput = System.in // without this, using Scanner on System.in won't work
}
task runCLITestApp(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'CLITestApp'
standardInput = System.in
}
// use cloudBuilder.py to invoke this jib task to build the container
// use cloudConfiguration.json to configure things like container version.
jib {
if (project.hasProperty('googleCloudProjectName') && project.hasProperty('imageName')) {
to {
image = "gcr.io/$googleCloudProjectName/$imageName"
}
container {
mainClass = 'ChessServer'
ports = ['8080']
creationTime = "USE_CURRENT_TIMESTAMP"
}
}
}
// make sure the required project properties are set for jib
task jibCheck {
doLast {
if (!project.hasProperty('googleCloudProjectName'))
throw new GradleException("When invoking the jib task, make sure to pass the cli arg -PgoogleCloudProject=[myGoogleCloudProject]\nThis should be the name of the google cloud project which container registry you want to push to.");
if (!project.hasProperty('imageName'))
throw new GradleException("When invoking the jib task, make sure to pass the cli arg -PimageName=[imageName]");
}
}
tasks.jib.dependsOn tasks.jibCheck
// src/main/jib is the default folder that jib looks for files to add to your container
// these files will be placed in the root / dir of the container
task moveFilesForJib(type: Copy) {
from "releaseFiles"
into "src/main/jib"
}
tasks.jib.dependsOn tasks.moveFilesForJib
Add the following to build.gradle. After rebuilding the project, see if the error goes away.
compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.1'
The solution was to run
./gradlew wrapper
Then in vscode run Java: Clean Workspace.

Configure .jar to expose its dependencies

I have 3 modules: annotations, annotation_processor and app.
annotations/build.gradle
apply plugin: 'java-library'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
annotation_processor/build.gradle
apply plugin: 'java-library'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
api project(":annotations")
api "com.squareup:javapoet:1.11.1"
}
repositories {
mavenCentral()
}
sourceCompatibility = "1.8"
targetCompatibility = "1.8"
task deleteJar(type: Delete) {
delete 'libs/annotations.jar'
}
task createJar(type: Copy) {
from('build/intermediates/bundles/release/')
into('libs/')
include('classes.jar')
rename('classes.jar', 'annotations.jar')
}
createJar.dependsOn(deleteJar, build)
and app/build.gradle
dependencies {
...
implementation files('libs/annotation_processor.jar')
annotationProcessor files('libs/annotation_processor.jar')
...
}
When I run the project I get the following error.
error: package com.annotations does not exist
If I include annotations as a project the project I can skip this error but then I get.
Caused by: java.lang.NoClassDefFoundError: com/annotations/ProviderApi
at com.annotation_processor.ProviderAnnotationProcessor.getSupportedAnnotationTypes(ProviderAnnotationProcessor.java:45)
at org.gradle.api.internal.tasks.compile.processing.DelegatingProcessor.getSupportedAnnotationTypes(DelegatingProcessor.java:47)
at org.gradle.api.internal.tasks.compile.processing.NonIncrementalProcessor.getSupportedAnnotationTypes(NonIncrementalProcessor.java:33)
at org.gradle.api.internal.tasks.compile.processing.DelegatingProcessor.getSupportedAnnotationTypes(DelegatingProcessor.java:47)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor.access$101(TimeTrackingProcessor.java:37)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor$2.create(TimeTrackingProcessor.java:68)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor$2.create(TimeTrackingProcessor.java:65)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor.track(TimeTrackingProcessor.java:117)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor.getSupportedAnnotationTypes(TimeTrackingProcessor.java:65)
I can't access any of the dependencies (Java Poet and annotation module) from annotation_processor even though I have replaced implementation with api. Which should've expose the dependencies, but haven't.
I need the dependencies of the .jar file in the app module.
I'm new to Java Library and it may be I'm making a basic mistake, but can't seem to figure out, I've been at it for more than a day now.
You have to create a multi module gradle project.
I provide a small snippet of a multi module project.
project(':module1') {
dependencies {
compile project(':module-service-api')
compile 'org.apache.commons:commons-lang3:3.3.2'
compile 'log4j:log4j:1.2.17'
}
}
//module-app depends on module-service-impl
project(':module2') {
dependencies {
compile project(':module1')
}
For more details about multi module project, refer to the file build.gradle in the following project.
https://github.com/debjava/gradle-multi-module-project-1
If you want to create a fat jar or one jar, you have to include Gradle shadow plugin so that you can distribute the jar file along with other dependencies.
Refer below the link.
https://plugins.gradle.org/plugin/com.github.johnrengelman.shadow

Protobuf generated classes cannot be found when using gradle

If I follow the instruction in the grpc-java readme and I use maven, the protobuf generated files appear in the target directory and are subsequently in the classpath for me to extend etc. However, when I use gradle, the generated classes appear in the build directory and are absent from the classpath. I'm fairly new to gradle so I'm not really sure why it's behaving so differently.
My build.gradle file
apply plugin: 'java'
apply plugin: 'com.google.protobuf'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.5'
}
}
group 'co.example'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile 'io.grpc:grpc-netty-shaded:1.15.1'
compile 'io.grpc:grpc-protobuf:1.15.1'
compile 'io.grpc:grpc-stub:1.15.1'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.5.1-1"
}
//noinspection GroovyAssignabilityCheck
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.15.1'
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
}
}
It looks like for gradle (if you want to use the generated stubs/server interfaces) in the project where your proto files live in (i.e. the project is not just for generating jars and publishing them) then you'll need to add generatedFilesBaseDir to your build.gradle file:
protobuf {
generatedFilesBaseDir = "$projectDir/src/main/java/generated"
...
}
Once you've done this, the stubs should be in your classpath.
public class SomeServer extends MyProtoClassGrpc.PDFExtractImplBase {}

build.gradle: compile group vs compile, buildscript, classpath

What is the difference between "compile group" and "compile"? Just another way to define a dependency?
Ex:
compile group: 'org.slf4j', name: 'slf4j-jcl', version: '1.7.21'
And i think this also will work:
compile("org.slf4j:slf4j-jcl:1.7.21")
Why do i have the declare mavenCentral() again and another dependencies block inside the buildscript block?
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.4.0.RELEASE")
}
}
From my point of view, when you compile something it will be in your classPath?
compile specifies an external dependency for the project you are building. compile requires group, name, and version. These can either be broken out or specified using the short form "group:name:version". see Gradle Dependency Management Basics
The buildscript block declares the dependencies of your gradle build itself while the normal dependencies block declares the dependencies of the project you are going to build

Is there any way of making IntelliJ IDEA recognizing Dagger 2 generated classes in a Java project?

Context
I have started a personal project in java with Gradle as the build system and I want to use Dagger 2 as a DI. The main reason of doing that is to get used to that library and be able to use it easily in bigger projects.
What have I tried
I've managed to make the Google sample runs on IntelliJ IDEA
Problem
IntelliJ IDEA keeps telling me that it cannot resolve the generated class (in this case DaggerCoffeeApp_Coffee). It's a bit annoying not to know if the written code is correct (specially when you are learning to use Dagger 2).
All java classes are the same as the Google sample. Here is my build.gradle file:
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile 'com.google.dagger:dagger:2.0.1'
compile 'com.google.dagger:dagger-compiler:2.0.1'
}
Question
Is there any way to make IntelliJ IDEA recognize DaggerCoffeeApp_Coffee as a generated class (and so make it possible to go to its implementation by `ctrl + left click)?
Simplest way I found:
Add idea plugin and add Dagger2 dependency like below:
plugins {
id "net.ltgt.apt" version "0.10"
}
apply plugin: 'java'
apply plugin: 'idea'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile 'com.google.dagger:dagger:2.11'
apt 'com.google.dagger:dagger-compiler:2.11'
}
Turn on Annotation Processing for IntelliJ: Go to Settings and search for Annotation Processors, check Enable annotation processing like below image:
Finally I made it!
I had to add the apt and the idea plugin so right now my build.gradle file look like this:
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "net.ltgt.gradle:gradle-apt-plugin:0.4"
}
}
apply plugin: "net.ltgt.apt"
apply plugin: 'java'
apply plugin: 'idea'
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile 'com.google.dagger:dagger:2.0.1'
apt 'com.google.dagger:dagger-compiler:2.0.1'
}
you must manually enable the annotation processing in IntelliJ.
From: Settings --> Build, Execution, Deployment --> Compiler --> Annotation Processors --> Enable annotation processing and Obtain processors from project classpath
then rebuild the project and you will find the generated classes in the project.
Please note that I have used this solution in a (java) android project.
I'm using version 2017.3.3 of IntelliJ IDEA, version 0.14 of the net.ltgt.apt plugin and version 2.14.1 of Dagger and as well as applying the idea plugin in the build.gradle file (as in Pelocho's answer) I found I also had to tell IntelliJ where it can find the sources generated by Dagger, as follows:
apply plugin: 'idea'
idea {
module {
sourceDirs += file("$buildDir/generated/source/apt/main")
testSourceDirs += file("$buildDir/generated/source/apt/test")
}
}
This is what I had to do in order to get Idea to work with Dagger2 and gradle.
Turn on annotation processing as shown in the answers above.
Add the following to the build.gradle file in order for Idea to see the generated classes as sources.
sourceDirs += file("$projectDir/out/production/classes/generated/")
Here's the full listing of my build.gradle
plugins {
id 'java'
id 'idea'
id "net.ltgt.apt" version "0.10"
}
idea {
module {
sourceDirs += file("$projectDir/out/production/classes/generated/")
}
}
repositories {
mavenCentral()
}
dependencies {
compile 'com.google.dagger:dagger:2.16'
apt 'com.google.dagger:dagger-compiler:2.16'
}
sourceCompatibility = 1.8
Also, I had to add the following gradle task (to my build.gradle file) to clear out my out directory. When I moved some files around and Dagger2 regenerated the source files, the out directory wasn't being cleared out :(. I also included this task in my run configuration, so that it gets triggered before I rebuild my project.
task clearOutFolder(type: Delete) {
delete 'out'
}
Here's the solution that worked for me:
File -> Project Structure -> (select your project under list of modules) -> Open 'Dependencies' tab
Then, click on green '+' sign, select 'JARs or directory' and select 'build/classes/main' folder.
Another solution would be to link folder with build class files using 'dependencies' block inside build.gradle:
https://stackoverflow.com/a/22769015/5761849
Using IntelliJ IDEA 2019.1 and Gradle 5.4.1, this seems to be enough:
plugins {
id 'java'
}
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testImplementation group: 'junit', name: 'junit', version: '4.12'
implementation 'com.google.dagger:dagger:2.23.1'
annotationProcessor 'com.google.dagger:dagger-compiler:2.23.1'
}
I don't know the minimal versions for which this solution works, though.
I had a similar problem, I could not find out the cause for a long time.
Just launched and the result surprised me.
Intellij Idea 2018.3.6 -
build.gradle:
plugins {
id "java"
}
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile 'com.google.dagger:dagger:2.11'
apt 'com.google.dagger:dagger-compiler:2.11'
}
The following worked for me on IntelliJ 2021.3.3 (UE)
plugins {
id 'java'
id 'idea'
id("com.github.johnrengelman.shadow") version "7.1.2"
}
idea {
module {
sourceDirs += file("$projectDir/build/generated/sources/annotationProcessor/java/main")
testSourceDirs += file("$projectDir/build/generated/sources/annotationProcessor/java/test")
}
}
group 'com.codigomorsa'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
annotationProcessor 'com.google.dagger:dagger-compiler:2.44'
implementation 'com.google.code.gson:gson:2.9.1'
implementation 'com.google.dagger:dagger:2.44'
testAnnotationProcessor 'com.google.dagger:dagger-compiler:2.44'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
}
test {
useJUnitPlatform()
}

Categories

Resources