I have the following project structure:
Root project 'rmi-tutorial'
+--- Project ':client'
+--- Project ':lib'
\--- Project ':server'
The path to clients main class looks like this:
client/src/main/java/client/ComputePi.java
my build.gradle for the client subproject loooks like this:
dependencies {
compile project(':lib')
}
mainClassName = "ComputePi"
The main build.gradle file is this one:
subprojects {
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'application'
repositories {
mavenCentral()
}
dependencies {
//compile project(':server')
//compile project(':client')
testCompile 'junit:junit:4.12'
}
version = '1.0'
jar {
manifest.attributes provider: 'gradle'
}
}
The generation of the jars works so far but the MANIFEST.MF file in the jar is wrong. It contains the following:
Manifest-Version: 1.0
provider: gradle
Where is my specified main class? When I try to execute the startscript that got created by the gradle application-plugin I get the error: couldn't find nor load main class
The jar contains all necessary class files
The application plugin does not produce a runnable JAR with Main-Class entry. Instead it generates a distribution with Windows and *nix start scripts where the main class is used and all libaries put to the class path.
If you want a runnable JAR, you have to configure it yourself, or use one of the plugins that produces a fat JAR, also including the dependencies into the runnable JAR (I don't like this, but it works if the target computer has the correct file associations set). If the target computer e. g. has associated JAR files with an archiving tool, double-clicking the JAR will open the JAR in the archiving tool, not run your application.
If you want to run your application, use gradlew run, or do gradlew installDist and then execute the application that is installed to build/install/.... That is how the application plugin works. With gradlew distZip or gradlew distTar you can create shippable archives of your application.
Related
Good day,
Base on this page, https://www.eclipse.org/webtools/community/tutorials/TopDownAxis2WebService/td_tutorial.html,
I am using eclipse to create a Top Down java bean web service, by using Axis2 runtime.
The different of mine, is I am using Red Hat JBoss EAP as my server.
After done the thing, I am now want to generate the war file and deploy in another Red Hat JBoss server. I can successfully generate the war file by right click on the project in my eclipse and export it as war, and the war file can successfully deploy into Jnoss server and the service can up successfully.
In the other way, I would like to try to use gradle command to generate the war file, instead of using eclipse to generate. Thus I run gradle clean build command to generate the war file. Yes, the war file can be generated but the file size lesser 10MB if compare with the one I generate throw eclipse.
And the war generate by gradle command, I will hit 404 when I view the service after I deployed into my Jboss server.
I extract both the war to compare, and found that the one using command is lack of the axis2-web library folder.
The following is my screen shot:
eclipse generated war file and with the 3 folders after I extract the war:
gradle clean build generated war file and with the 2 folders after I extract the war:
As you can see, the one generate by gradle command, lack of the axis2-web library folder, thus I believe this is why it can be access successfully after deployed.
and the following is my build.gradle:
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'eclipse'
apply plugin: 'application'
mainClassName = "EAIDelegateBeanServiceSkeleton"
repositories {
mavenCentral()
maven {
url "https://packages.confluent.io/maven"
}
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile "com.google.guava:guava:17.0"
compile 'com.googlecode.json-simple:json-simple:1.1.1'
compile 'org.apache.kafka:kafka-clients:3.1.0'
compile 'com.google.code.gson:gson:2.8.2'
compile 'io.confluent:kafka-json-serializer:6.2.0'
compile "org.springframework.kafka:spring-kafka:2.6.13"
compile "org.springframework:spring-web:5.2.19.RELEASE"
testImplementation "junit:junit:4.12"
}
I would like to ask for help on how can I configure so that I can generate the correct war file by using gradle command.
I found out the solution is configure the webContent/web-inf under war in build.gradle:
war {
webInf { from 'WebContent/WEB-INF' }
}
My gradle build file is
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'
}
apply plugin: 'java'
jar {
from configurations.runtime
manifest {
attributes(
'Created-By':'Gmack',
'Main-Class':'myapprunner.App',
'Class-Path':'mydaos-1.0.jar'
)
}
}
allprojects{
repositories {
jcenter()
}
}
subprojects {
version = '1.0'
apply plugin: 'java'
}
dependencies {
// This dependency is used by the application.
implementation 'com.google.guava:guava:27.1-jre'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
// Compile Project for dependency
compile project(':mydaos')
}
application {
// Define the main class for the application
mainClassName = 'myapprunner.App'
}
When I run the app using java -jar myapprunner.jar
I get a ClassNotFoundException
Caused by: java.lang.ClassNotFoundException: com.mydaos.Library
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 1 more
I can confirm that the jar has been packed. Not sure why this is not picking things up.
Any help would be appreciated.
Thanks,
Plugin java is being applied twice and com.mydaos.Library is likely being pulled in from compile project(':mydaos') (or 'Class-Path':'mydaos-1.0.jar'). Would assume the project does not build or the class path is wrong.
Dependency classes (projects/external jars) aren't packed inside your jar by default.
You are using the application plugin which bundles your classes, your dependencies and an execution script in a zip so you should use that. The plugin also adds a "run" task to your project to run your main class via gradle for development purposes. See the application plugin docs for more info
If you want to pack your dependencies inside your jar (known as an uber jar) see here. I suggest you stop using the application plugin if you do this
'Class-Path':'mydaos-1.0.jar'
This assumes that mydaos-1.0.jar is in the same folder you are running java -jar ... from which is likely not the case
I am doing the simple HelloWorld example from https://spring.io/guides/gs/gradle/.
I had to do some changes (I'm using Gradle 5.2.1 on Ubuntu 18) to the build.gradle. I used gradlew wrapper. I managed to get tasks like 'build' and 'run' working. Everything is generated correctly, it seems. But running the app without gradle using the generated build/scripts/<appscript> does not work. Running the jar with
java -jar build/libs/hello-1.0.jar
works. But
./build/scripts/sayhello
Does not work and produces an error:
erno#moongate:~/Projects/java/sayhello$ ./build/scripts/sayhello
Error: Could not find or load main class hello.HelloWorld
Caused by: java.lang.ClassNotFoundException: hello.HelloWorld
Project file structure is as suggested:
sayhello/
build.gradle
gradlew
src/
main/
java/
hello/
Greeter.java
HelloWorld.java
I had to add the manifest and the mainclass attribute to the build configuration file as it seems that the gradle init --type java-application does not do it. Meaning that even trying to run the gradle generated base project does not work.
My build.gradle is like this:
plugins {
id 'java'
id 'application'
}
mainClassName = 'hello.HelloWorld'
repositories {
mavenCentral()
jcenter()
}
dependencies {
compile "joda-time:joda-time:2.10"
testCompile "junit:junit:4.12"
}
jar {
manifest {
attributes(
'Main-Class': 'hello.HelloWorld'
)
}
baseName = 'hello'
version = '1.0'
}
The problem with the startScripts task is that it generates a very basic script. It does not make sure dependent jars are in the right places - it expects this to be done by you. Also it assumes that you will be running the script from a directory it refers to as the $APP_HOME and this folder needs to contain a lib folder which contains all the jars your app needs.
My very hacky solution is to generate an even more basic unix script instead of relying on the default one.
startScripts {
dependsOn jar
doFirst {
unixStartScriptGenerator = configure(new CustomUnixStartScript()) {
classpath = configurations.runtimeClasspath + jar.outputs.files
}
}
}
class CustomUnixStartScript implements ScriptGenerator {
#InputFiles
FileCollection classpath
#Override
void generateScript (JavaAppStartScriptGenerationDetails details, Writer destination) {
destination << """java -classpath $classpath.asPath ${details.mainClassName}"""
}
}
You can extend this as you see fit.
After cleaning when i try to build gradle i get an error in the console saying:
package org.json does not exist import org.json.JSONObject;
cannot find symbol
symbol : class JSONObject
there are red marks in the java file at all places where jsonobject and json array exists.
I have put the folder web inf/lib that contains all the jar files inside the src/main/webapp directory that i have created.
currently the contents of my build.gradle file are:
/*
* This build file was auto generated by running the Gradle 'init' task
* by 'i2cdev001' at '14/11/18 3:11 PM' with Gradle 2.14.1
*
* 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 guide available at https://docs.gradle.org/2.14.1/userguide/tutorial_java_projects.html
*/
// Apply the java plugin to add support for Java
apply plugin: 'java'
apply plugin: 'war'
// In this section you declare where to find the dependencies of your project
repositories {
// Use 'jcenter' for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
}
// In this section you declare the dependencies for your production and test code
dependencies {
// The production code uses the SLF4J logging API at compile time
compile 'org.slf4j:slf4j-api:1.7.21'
// Declare the dependency for your favourite test framework you want to use in your tests.
// TestNG is also supported by the Gradle Test task. Just change the
// testCompile dependency to testCompile 'org.testng:testng:6.8.1' and add
// 'test.useTestNG()' to your build script.
testCompile 'junit:junit:4.12'
}
Note: Also in the project properties i am unable to see any jar files under the Web App Libraries in the java build path tab. I can see only access rules:no rules defined and native library locations:(none)
As your project is gradle project, Adding jar manually wont work.. You have to mention path where you have kept all your jar files in your build.gradle file.
Mention your jar file path in repository under flatDir {}:
repositories {
jcenter()
flatDir {
dirs 'libs'
}
}
Then you have to add which jar from that folder you have mentioned above (ie libs)
dependencies {
compile 'gson-0.1.0'
}
I've made a project in maven and spring boot. After build it via maven it worked perfect.
After all I decided to swap my project into gradle. And now, after:
gradle build
The following exception is comming.Error:
Error: Could not find or load main class
Here are things I checked before I asked this question:
made sure that I have main method (which i obviously have, maven did thing great)
checked path to main class in manifest and in jar task in gradle
found out that compiled class is in specified jar in specified path
Made a jar task in gradle that looks like this:
jar {
manifest {
attributes 'Main-Class': 'pl.sygnity.schedulein.App'
}
}
I have no idea what i can do more about it.
Could you help me?
Edit.
It's important i wish to use my program as jar so:
java -jar xx.jar
Edit2.
gradle run
makes my App start. So it looks like as if gradle build is not working somehow...
You need to define the main class in the build.gradle file. (You may have more than one, and you need to choose which one to use)
I like to do it with Gradle - the application plugin
apply plugin: 'application'
mainClassName = "<Your main class>"
Then you can run gradle install to build the program with an executor.
You need to modify your gradle manifest.
jar {
manifest {
attributes <...>
'Main-Class': 'main.myMainClass'
}
}
Otherwise you can change the path of your source fields like this.
sourceSets.main.java.srcDirs = ['MAINFOLDER'] // 'src'
So i find out that these steps made my jar working well.
Removed
apply plugin: 'maven'
Added
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
Bit weird but maybe someone will be struggling with same kind of problem. Thanks for help.