Gradle building rest spring app can't find main class - java

I'm trying to do a http://spring.io/guides/gs/rest-service/ tutorial, and I did everything like it is in tutorial.
When I was trying to build with gradle with the gradle.build from the tutorial gradle build failed because of missing
springBoot {
mainClass = "main.java.hello.Application"
}
I did add it and now compilation start and finish correctly, but as soon as I'm trying to do
java -jar build/libs/gs-rest-service-0.1.0.jar
It throws an error
I have no idea what to do with it. Any help?

It should be hello.Application. main/java is a part of package name / project dir structure.
When added the following piece of code to build.gradle:
springBoot {
mainClass = "hello.Application"
}
both ./gradlew clean bootRun and ./gradlew clean build with java -jar build/libs/gs-rest-service-0.1.0.jar work well.

The above error is due to the build do not includes our Web RESTful Service main application class files into the gs-rest-service-0.1.0.jar file because of the src/main/java/hello, folder is not under the gradle build scope.
In order to avoid the above error or any other errors for https://spring.io/guides/gs/rest-service/ tutorial
Please follow the steps below.
My Folder structure as follows.
C:\MyWebService\src\main\java\hello
Put your build.gradle file under your main folder e.g "MyWebService" not in your hello or any other folder hence "gradle build' will be successful.
Using DOS cmd navigate to your main folder e.g C:\MyWebService\ where src should be the first sub folder.
Run the gradle commands.
gradle
gradle tasks
gradle wrapper
gradlew clean build -- final build
or gradlew clean bootRun -- run before build
You will find your gs-rest-service-0.1.0.jar under your C:\MyWebService\build\libs folder.
Finally invoke spring web service from main folder e.g C:\MyWebService\
java -jar build/libs/gs-rest-service-0.1.0.jar
To check Spring RESTful Web Service by hitting below url in the browser, JSON data will be returned.
http://localhost:8080/greeting
{"id":1,"content":"Hello, World!"}
Now you should be successful with completing the Spring RESTful Web Service tutorial.
N.B: Please do not modify your original build.gradle file provided
on the tutorial.

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'application'
Add the above highlighted line in the build.gradle

Related

Android Studio project could not synchronise with Gradle files

I am a new app developer and, I am trying to build up the foundation of the knowledge by following the instructions from an online course (https://developer.android.com/codelabs/build-your-first-android-app#8) given by the android developer page in using Android Studio with Java.
After I add the lines to the project gradle file:
def nav_version = "2.3.0-alpha04"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
and to the app gradle file:
apply plugin: 'androidx.navigation.safeargs'
My project is failed to synchronize with the Gradle files. Could someone solve the error and explain this error to me? I have tried to rebuild the project, but it didn't work out.
Below is the code and the error:
Error:
class org.codehaus.groovy.ast.expr.TupleExpression cannot be cast to class org.codehaus.groovy.ast.expr.ArgumentListExpression (org.codehaus.groovy.ast.expr.TupleExpression and org.codehaus.groovy.ast.expr.ArgumentListExpression are in unnamed module of loader org.gradle.internal.classloader.VisitableURLClassLoader #42d80b78)
class org.codehaus.groovy.ast.expr.TupleExpression cannot be cast to class org.codehaus.groovy.ast.expr.ArgumentListExpression (org.codehaus.groovy.ast.expr.TupleExpression and org.codehaus.groovy.ast.expr.ArgumentListExpression are in unnamed module of loader org.gradle.internal.classloader.VisitableURLClassLoader #42d80b78)
Gradle's dependency cache may be corrupt (this sometimes occurs after a network connection timeout.)
Re-download dependencies and sync project (requires network)
The state of a Gradle build process (daemon) may be corrupt. Stopping all Gradle daemons may solve this problem.
Stop Gradle build processes (requires restart)
Your project may be using a third-party plugin which is not compatible with the other plugins in the project or the version of Gradle requested by the project.
In the case of corrupt Gradle processes, you can also try closing the IDE and then killing all Java processes.
Code:
enter image description here
enter image description here
enter image description here
Can you try below lines As It's working fine for me.
// Add to Porject level gralde file
def nav_version = "2.3.5"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
//Add to Module level gralde file.
id "androidx.navigation.safeargs.kotlin"
Difference b/w androidx.navigation.safeargs.kotlin and androidx.navigation.safeargs
id 'androidx.navigation.safeargs' is for Java/Kotlin mixed modules
id 'androidx.navigation.safeargs.kotlin' is for pure Kotlin modules.
Plus put the plugin at the end e-g check below example
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
id 'androidx.navigation.safeargs.kotlin'
}
Other Info, You can try below options as well.
-Check If the Gradle is on online mode not offline (Right side menu bar click on Gradle =//= check If that sign is not pressed.)
-Clean your project then rebuild
-Invalidate Cache and Restart

How to run a Gradle task on a compiled jar without having its sources?

I have a compiled jar with JUnit tests that I want to run from a docker container.
I want to do it with a Gradle task.
First, I will compile the jar and copy it with all its dependencies to a Gradle-based image.
(Or I can create a fat jar which will contain all the third party compiled to a .class).
Then I want to run the task - this task will only run tests according to a test name, JUnit tag, etc.
Is it possible to run a Gradle task on a compiled jar without having its sources?
What should I include in this image beside the gradle.build file for it to work?
Thank you
Gradle fetch transitive dependencies and run its tests in test process by default, so you can use this feature in your case.
Note that abstract classes are not executed. In addition, be aware that Gradle scans up the inheritance tree into jar files on the test classpath. So if those JARs contain test classes, they will also be run.
Gradle tests detection document.
Here is how to do it in your case :
Create an empty Gradle project and apply the java plugin.
import the test dependencies tools with the needed scopes in the dependencies section.
import myApp.jar as a local dependency.
Configure the test task (add needed properties and args).
Run Gradle test with the specific properties.
build.gradle example :
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
// just examples change with needed unit tests dependencies
testImplementation('org.junit.jupiter:junit-jupiter-api:5.4.2')
testRuntime('org.junit.jupiter:junit-jupiter-engine:5.4.2')
// the target jar file
compile file("/myApp.jar")
}
project.ext.testName = project.hasProperty("testName") ?
project.property("testName") : "*"
test {
useJUnitPlatform()
filter {
//include specific method in any of the tests
includeTestsMatching "$testName"
}
}
Now the Gradle test command will run the target tests in myApp.jar.
For more information about it check the Testing in Java & JVM projects official Gradle documents

Added Gradle to Java project "Exception ... java.lang.NoClassDefFoundError"

I had an existing project without Gradle and needed to add com.google.code.gson:gson:+ library to work with JSON objects. To begin with I ran either gradle init or gradle build, I'm not sure. This caused my java classes with a main() not to run as the source path was wrong/changed. I have changed the structure following advice to at least get the classes to compile and run, but I still have this warning in run configurations "Warning: Class 'Main' not found in module 'src'" ;
If I set Use classpath of module to src.main, the warning goes away but when I run Main.main() Gradle seems to execute Gradle tasks, like this - this will run indefinitely;
Here is my project structure;
This is my build.gradle file;
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java project to get you started.
* For more details take a look at the Java Quickstart chapter in the Gradle
* User Manual available at https://docs.gradle.org/6.3/userguide/tutorial_java_projects.html
*/
plugins {
// Apply the java plugin to add support for Java
id 'java'
// Apply the application plugin to add support for building a CLI application.
id 'application'
// idea plugin? // I added this to original build.gradle file
id 'idea'
}
repositories {
// Use jcenter for resolving dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
mavenCentral()
google()
}
dependencies {
// This dependency is used by the application.
implementation 'com.google.guava:guava:28.2-jre'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
// For use with JSONUtil class // I added this to original build.gradle file
compile 'com.google.code.gson:gson:+'
}
application {
// Define the main class for the application.
mainClassName = 'java.Main' // changed to 'Main' and I can `gradle run` seems to actually run Main.java
}
I have imported com.google.gson.JsonObject and com.google.gson.JsonParser from com.google.gson:gson:2.8.6 library, with no code inspection warnings, i.e available at compile time. If I run my code with a JsonObject jsonObject = new JsonObject I get the error;
Exception in thread "main" java.lang.NoClassDefFoundError: com/google/gson/JsonParser
at HttpUtils.getAccessToken(HttpUtils.java:80)
at Main.auth(Main.java:75)
at Main.play(Main.java:36)
at Main.main(Main.java:17)
Caused by: java.lang.ClassNotFoundException: com.google.gson.JsonParser
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 4 more
Line 80 of HttpUtils.java;
JsonObject jsonResponse = JsonParser.parseString(response.body()).getAsJsonObject(); // todo: status 200 "success" else failed
accessToken = jsonResponse.get("access_token").getAsString();
System.out.println(accessToken);
I understand this means that JVM can't compile a .class for JsonParser? I suppose this means the compiler has no knowledge of the library existing, which makes me suspect that Gradle isn't configured properly with the project, as it has downloaded the library, but not added a path to it?
I have tried gradle cleanIdea and then gradle idea. I have rebuilt the the project. I have "Mark directory as source root" on various directories for testing being careful to revert when it failed to change behaviour.
Edit;
I have added a package com.example in the src.main.Java directory and added the java files.
I edited run configuration for Main.java to
Main class: com.example.Main
Use classpath of module: src.main
I also changed the build.gradle file to;
application {
// Define the main class for the application.
mainClassName = 'com.example.Main'
}
Main runs but I am stuck at this point, which seems to run indefinitely;
Also, I am sure I right clicked on build.gradle and selected import, although I can't recreate this as the option isn't available now.
Edit 2;
I have been able to get the classes Main and Test with main() to run by putting them in the test/java/src package, and using unusual run configuration with warnings. Although on closer inspection, it seems to be running code that is previously compiled somewhere, as any changes I make aren't reflected in output.
Here is my project structure at the moment;
This is my run configuration that actually runs main in the standard output console, rather than a Gradle Task. It's clearly wrong, as Main is not in the com.example package or src.main module. If I set it correctly using module src.test and main class src.Main Gradle runs as screenshot 5.
Edit 3;
I see now that Gradle has took over responsibility to build and run the java files. I didn't know running in the output could be done with another CLI app and I admit it confused me, so please forgive anything above that seems stupid, I'm learning and figuring this out as I go.
I found in InteliJ settings Build, Execution, Deployment > Build Tools > Gradle I can change the Build and run using option between InteliJ IDEA and Gradle. The only issue I'm having with Gradle now I understand what is happening is Gradle doesn't seem to update my .class files when I run my main() with Gradle. Maybe this is for another question though.
mainClassName = 'java.Main' // changed to 'Main' and I can "gradle run" seems to actually run Main.java
This is not correct. Based on screenshot - you have not package named java (also I doubld that this is a valid name for a Java package). Create proper package inside src/main/java directory and specify it in the Main source file and in build.gradle file.
Also make sure you have imported build.gradle file in IDE, see Link a Gradle project to an IntelliJ IDEA project

Publishing jar in Gradle

I've been reading about publishing jar in the Gradle manual page (section 7.2.4).
The following code is provided:
uploadArchives {
repositories{
flatDir{
dirs 'repos'
}
}
}
I added that piece of code in my build script but there is no repos dir was created in my project-root directory after gradle build was executed. What does it actual do? Is there a documentation for uploadArchive and the others methods?
As the section 7.2.4. Publishing the JAR file, in the mentioned docs suggests, the file is not uploaded by the build but by the task uploadArchives.
To publish the JAR file, run gradle uploadArchives.
Further in the documentation there are the chapters 8.6. Publishing artifacts (with an example how to publish to ivy and maven (Example 8.8, 8.9)) and 52.4. Publishing artifacts.
The task is of type Upload, where one can delve deeper for how the task is working.

Maven/Gradle working overlay example with eclipse

I have an EAR project which should contain one or more skinny WARs. I already tried everything to get that project working with eclipse but just couldn't make eclipse do the same as the tools(maven and gradle) do when I run them from the command line.
Are there no working examples I could use to get my projects working with eclipse? Please help me, I alread ask myself if anyone is really using these tools like I want them to for such kind of projects.
In my last project experience I have problem with supporting the maven with Eclipse. Because of problem in Eclipse m2 plugin.
So the best solution for me was build an ear from the command line by some shell scripts for example. To open project in IDE I used maven eclipse plugin, thus I generated eclipse workspace by maven.
Using Eclipse External Tools you can run shell script to build/or run your EE application from the command line pretty convenient.
The same applies to the gradle, but looks like Eclipse Gradle plugin is more stable, and now I use plugin in my Gradle project.
If it will be useful for you, you can review github test project to illustrate how to make maven multymodule war project. Also you can find short explanation how to generate eclipse workspace for this project. After workspace generated you can import as Existing Project into your workspace.
Here is a sample Ear project containing war(Refer to img below for dir structure)
MainDir contain 2 files and 1 directory called war.
File settings.gradle contains
include 'war'
File build.gradle contains
apply plugin: 'ear'
repositories {
mavenCentral()
}
dependencies {
deploy project(':war')
//earlib group: YOUR_DEPENDENCIES
}
build.gradle for war directory contains
apply plugin: 'war'
apply plugin: 'jetty' // you can call gradle jRW
repositories {
mavenCentral()
}
dependencies {
//compile group: YOUR_DEPENDENCIES
}
httpPort = 8080 //jetty start port
stopPort = 8081 //jetty stop port
File HelloWorld.java contains
public class HelloWorld {
public String getHello() {
return "Hello world!";
}
}
File index.jsp contains
<jsp:useBean id="helloWorld" class="your_package.HelloWorld"/>
<html>
<p>${helloWorld.hello}</p>
</html>
Now open cmd->MainDir(or you can search eclipse-marketplace for gradle and execute this step directly from eclipse) and type
gradle jRW//short for jettyRunWar
now open
localhost:8080/war/

Categories

Resources