I have a project structure as follows:
└── src
├── main
│ ├── java
│ │ ├── MessageServlet.java
│ └── webapp
│ ├── META-INF
│ │ └── context.xml
│ ├── WEB-INF
│ │ └── web.xml
│ ├── index.html
│ └── style.css
└── test
└── java
I also have a tomcat server which I run using the gradle below. The tomcat server starts and displays the index.html page. But, when I try to run the servlet i get following error message:
HTTP Status 500 - Error instantiating servlet class MessageServlet
build.gradle
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.bmuschko:gradle-tomcat-plugin:2.2.4'
}
}
apply plugin: 'com.bmuschko.tomcat'
apply plugin: 'war'
apply plugin: 'idea'
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
compile 'org.mongodb:mongo-java-driver:3.3.0'
compile 'com.google.code.gson:gson:2.2.4'
def tomcatVersion = '8.0.42'
tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}",
"org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}",
"org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}"
}
QUESTION
I want to run the project on my tomcat server via this gradle. How do I make the gradle execute MessageServlet.java together with tomcat?
Related
I am migrating multi-module Gradle Java project from Gradle 4.10 to Gradle 6.3.
Project structure looks like the following:
├── build.gradle
├── our-webapp
│ ├── build.gradle
│ └── src
│ ├── main
│ ├── integrationTest
│ └── test
└── cli-util
├── build.gradle
└── src
├── main
├── integrationTest
└── test
cli-util has a dependency on webapp to use it's classes.
build.gradle looks like:
plugins {
id 'java'
}
sourceSets {
integrationTest {
compileClasspath += sourceSets.main.output + sourceSets.test.output
runtimeClasspath += sourceSets.main.output + sourceSets.test.output
java.srcDir 'src/integrationTest/java'
resources.srcDir 'src/integrationTest/resources'
}
}
configurations {
integrationTestImplementation.extendsFrom testImplementation
integrationTestRuntime.extendsFrom testRuntime
}
dependencies {
implementation project(':our-webapp')
}
task integrationTest(type: Test) {
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
}
And now what is interesting is that tests under cli-util/src/intergrationTest are working fine in Intellij IDEA but they are failing from terminal whenever there is an import of a class defined in webapp project. The error is java.lang.NoClassDefFoundError: com/example/web/SomeClass.
I tried different approaches already, including the use of java-library plugin in cli-util project and importing webapp project like api project(':our-webapp') but it still fails.
Same issue in Gradle 5.6.x.
Is there some special change I have take into account to make it work?
I have a Gradle multi module project that uses the Mapstruct annotation processor for data type mapping across Java modules. The Gradle build works fine but when I import the project into IntellJ IDEA 2019.3 I get an unexpected annotation processor configuration.
The project structure looks like this
.
├── build.gradle
├── module1
│ └── src
│ └── main
│ └── java
│ └── io
│ └── wangler
│ └── mapstruct
│ ├── ApplicationModule1.java
│ ├── Person.java
│ ├── PersonDTO.java
│ └── PersonMapper.java
├── module2
│ └── src
│ └── main
│ ├── generated
│ │ └── ch
│ │ └── silviowangler
│ │ └── mapstruct
│ │ └── CarMapperImpl.java
│ └── java
│ └── ch
│ └── silviowangler
│ └── mapstruct
│ ├── ApplicationModule2.java
│ ├── Car.java
│ ├── CarDTO.java
│ └── CarMapper.java
└── settings.gradle
and the build.gradle that registers the annotation processor for module1 and module2.
subprojects { p ->
apply plugin: 'java-library'
apply plugin: 'groovy'
repositories {
jcenter()
}
dependencies {
annotationProcessor 'org.mapstruct:mapstruct-processor:1.3.1.Final'
implementation 'org.mapstruct:mapstruct:1.3.1.Final'
testImplementation 'org.codehaus.groovy:groovy-all:2.5.8'
testImplementation 'org.spockframework:spock-core:1.3-groovy-2.5'
testImplementation 'junit:junit:4.12'
}
}
When I compile the project using ./gradlew compileJava all works out fine and I get no compilation errors.
But when I run Rebuild Project withing IntelliJ I get a compilation error in module1 since IntelliJ does not have an annotation processor registered for module1.
Error:(6, 35) java: cannot find symbol
symbol: class PersonMapperImpl
location: class io.wangler.mapstruct.ApplicationModule1
Am I doing something wrong here or is this a known IntelliJ issue? The source code for this example can be found at https://github.com/saw303/idea-annotation-processors
I faced the same issue in IDEA 2019.3. Looks like a bug.
It occurs only if two modules has the same set of annotation processors.
To solve the problem you need to add any library using annotationProcessor directive to one of modules. It does not have to be a real annotation processor. This one is working for me:
annotationProcessor "commons-io:commons-io:${commonsIoVersion}"
I have created a defect in JerBrains bugtracker: IDEA-230337
This hello world project runs fine, but where is the hello_api-latest.jar file? (Regardless that the client doesn't actually "need" the JAR, it should still download.)
The JAR is on the classpath:
thufir#mordor:~/NetBeansProjects/hello_client$
thufir#mordor:~/NetBeansProjects/hello_client$ gradle clean build;java -jar build/libs/hello_client.jar
:clean
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:startScripts
:distTar
:distZip
:assemble
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build
BUILD SUCCESSFUL
Total time: 1.229 secs
hello world
thufir#mordor:~/NetBeansProjects/hello_client$
thufir#mordor:~/NetBeansProjects/hello_client$ jar -xf build/libs/hello_client.jar
thufir#mordor:~/NetBeansProjects/hello_client$
thufir#mordor:~/NetBeansProjects/hello_client$ cat META-INF/MANIFEST.MF
Manifest-Version: 1.0
Main-Class: net.bounceme.mordor.Main
Class-Path: hello_api-latest.jar
thufir#mordor:~/NetBeansProjects/hello_client$
thufir#mordor:~/NetBeansProjects/hello_client$ tree build
build
├── classes
│ └── main
│ └── net
│ └── bounceme
│ └── mordor
│ └── Main.class
├── dependency-cache
├── distributions
│ ├── hello_client.tar
│ └── hello_client.zip
├── libs
│ └── hello_client.jar
├── scripts
│ ├── hello_client
│ └── hello_client.bat
└── tmp
├── compileJava
│ └── emptySourcePathRef
└── jar
└── MANIFEST.MF
13 directories, 7 files
thufir#mordor:~/NetBeansProjects/hello_client$
build file:
apply plugin: 'java'
apply plugin: 'application'
sourceCompatibility = '1.8'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
if (!hasProperty('mainClass')) {
ext.mainClass = 'Main'
}
mainClassName = 'net.bounceme.mordor.Main'
repositories {
mavenCentral()
maven { url "https://jitpack.io" }
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.10'
compile 'com.github.THUFIR:hello_api:latest'
}
jar {
manifest {
attributes ('Main-Class': 'net.bounceme.mordor.Main',
"Class-Path": configurations.compile.collect { it.getName() }.join(' '))
}
}
Notably, the jitpack dependency doesn't show in Netbeans:
The build artifact at the end of the log would seem to indicate that the JAR, hello_api-latest.jar, was found:
latest
commit 244c611ae48dc95daee544fbfb5767ae1f961e10
Author: thufir
Date: Fri Feb 5 05:39:47 2016 -0800
increment
submodule status:
Run gradle build
Gradle build script
WARNING: Gradle wrapper not found. Please add. Using default gradle to build.
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
------------------------------------------------------------
Gradle 2.7
------------------------------------------------------------
Build time: 2015-09-14 07:26:16 UTC
Build number: none
Revision: c41505168da69fb0650f4e31c9e01b50ffc97893
Groovy: 2.3.10
Ant: Apache Ant(TM) version 1.9.3 compiled on December 23 2013
JVM: 1.8.0_60 (Oracle Corporation 25.60-b23)
OS: Linux 3.14.32-xxxx-grs-ipv6-64 amd64
0m0.684s
Getting a list of gradle tasks
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
Found javadoc task
WARNING:
Gradle 'install' task not found. Please add the 'maven' or 'android-maven' plugin.
See the documentation and examples: https://jitpack.io/docs/
Looking for android-library
Looking for com.android.application
Adding maven plugin
Running: gradle clean -Pgroup=com.github.THUFIR -Pversion=latest -xtest install
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
:clean UP-TO-DATE
:compileJava
Download https://repo1.maven.org/maven2/org/codehaus/groovy/groovy-all/2.4.1/groovy-all-2.4.1.pom
Download https://repo1.maven.org/maven2/org/codehaus/groovy/groovy-all/2.4.1/groovy-all-2.4.1.jar
:processResources UP-TO-DATE
:classes
:jar
:install
BUILD SUCCESSFUL
Total time: 1.883 secs
Gradle exit code 0
Looking for artifacts...
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
Found artifact: com.github.THUFIR:hello_api:latest
EXIT_CODE=0
2016-03-10T09:47:34.133966887Z
Exit code: 0
Build artifacts:
com.github.THUFIR:hello_api:latest
Files:
com/github/THUFIR/hello_api/latest
com/github/THUFIR/hello_api/latest/build.log
com/github/THUFIR/hello_api/latest/hello_api-latest.jar
com/github/THUFIR/hello_api/latest/hello_api-latest.pom
com/github/THUFIR/hello_api/latest/hello_api-latest.pom.md5
com/github/THUFIR/hello_api/latest/hello_api-latest.pom.sha1
but where was it downloaded to?
see also:
https://stackoverflow.com/a/22724504/262852
https://stackoverflow.com/a/30094915/262852
https://stackoverflow.com/a/34329145/262852
UPDATE
here it is:
thufir#mordor:~$
thufir#mordor:~$ tree .gradle/ | grep latest
│ │ │ └── latest
│ │ │ │ └── hello_api-latest.pom
│ │ │ └── hello_api-latest.jar
│ │ │ │ └── latest
│ │ │ │ └── latest
thufir#mordor:~$
As with any external dependency, it is downloaded to the gradle cache. The default location is ~/.gradle
I'm trying to use application.properties to bean datasource but it seems that spring boot does not find the file or something like.
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
Here my structure:
.
├── build.gradle
└── src
└── main
├── java
│ └── com
│ └── companies
│ ├── CompanyApplication.java
│ ├── config
│ │ └── WebMvcConfig.java
│ ├── controller
│ │ └── HelloWorldController.java
│ └── model
│ ├── Article.java
│ ├── daoInterface
│ │ └── ArticleDaoInterface.java
│ ├── daoTemplates
│ │ └── ArticleDao.java
│ └── mappers
│ └── ArticleMapper.java
├── resources
│ └── application.properties
└── webapp
└── WEB-INF
└── pages
└── hello.jsp
I've try to move application.properties file from resources to config and nothing.
application.properties:
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/name
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
build.gradle
buildscript {
repositories {
//Required repos
mavenCentral()
maven { url "http://repo.spring.io/snapshot" }
maven { url "http://repo.spring.io/milestone" }
}
dependencies {
//Required dependency for spring-boot plugin
classpath "org.springframework.boot:spring-boot-gradle-plugin:1.2.6.RELEASE"
}
}
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'spring-boot'
jar {
baseName = 'companies'
version = '0.2'
}
war {
baseName = 'companies'
version = '0.1'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
maven { url "http://repo.spring.io/snapshot" }
maven { url "http://repo.spring.io/milestone" }
}
dependencies {
compile 'org.springframework.boot:spring-boot-starter-web'
compile("org.springframework.boot:spring-boot-starter")
compile("org.springframework:spring-jdbc")
compile('org.springframework.boot:spring-boot-starter-jdbc:1.2.6.RELEASE')
testCompile("junit:junit")
//Required dependency for JSP
compile 'org.apache.tomcat.embed:tomcat-embed-jasper'
}
And where I'm trying to autowire the dataSource:
package com.companies.model.daoTemplates;
import com.companies.model.Article;
import com.companies.model.daoInterface.ArticleDaoInterface;
import com.companies.model.mappers.ArticleMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import javax.sql.DataSource;
import java.util.List;
#Repository
public class ArticleDao implements ArticleDaoInterface {
private JdbcTemplate jdbcTemplateObject;
private final String DB_NAME = "articles";
#Override
#Autowired
public void setDataSource(DataSource ds) {
this.jdbcTemplateObject = new JdbcTemplate(ds);
}
#Override
public List<Article> listArticle() {
String SQL = "select * from " + DB_NAME + " where inactive = false ORDER BY name";
List <Article> article = jdbcTemplateObject.query(SQL,
new ArticleMapper());
return article;
}
}
CompanyApplication.java
package com.companies;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
#Configuration
#ComponentScan
#EnableAutoConfiguration
public class CompanyApplication {
public static void main(String[] args) {
SpringApplication.run(CompanyApplication.class, args);
}
}
I cannot find where I'm failing at.
As #M. Deinum mentioned in his comment it seems to be a dependency configuration problem. You need a dependency on spring-jdbc for an embedded database to be auto-configured.
Please make sure you've followed on the documentation
You should also check out this spring-boot-jdb sample
Spring boot is mostly based on the principle than putting a specific jar in the classpath will trigger the activation of the related functionality. Spring boot is scanning the classpath at startup and will start "everything he found" except if you disable it by using annotation.
So to have Spring Boot initializing a DataSource you must have one of the following dependencies:
- spring-boot-starter-jdbc : will allow to use the DataSource and JDBC stuff.
- spring-boot-starter-data-jpa : will load the JPA and so the DataSource as a sub-module
I got a similar error and I solved it by adding the following dependency
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.5.0</version>
</dependency>
This should be the correct declaration of your runner class:
package com.companies;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class CompanyApplication {
public static void main(String[] args) {
System.exit(SpringApplication.exit(
SpringApplication.run(CompanyApplication.class, args)));
}
}
Amidst other things, it will auto-initialize your DataSource from the application.properties.
EDIT: in your application.properties you should have entries similar to these, which are specific for an Oracle DataSource:
spring.datasource.url=jdbc:oracle:thin:#<hostaddr>:<port>:<instance_name>
spring.datasource.username=<username>
spring.datasource.password=<password>
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
I've faced this problem and figured out that implementation of DataSource is placed in Tomcat libs. So for 8th tomcat you going to include org.apache.tomcat.jdbc.pool.DataSource class that placed in org.apache.tomcat:tomcat-jdbc:jar:8.0.36
I had the same problem. In my case I solved it by adding the dependency for the mysql java connector.
In an android project, I want to use a shared model library with the REST Server(JPA)
Project structure:
├── android
│ └ ...
│
├── model
│ ├── build.gradle
│ └── src
│ └── com
│ └── model // error at runtime
│ └── Customer.java
├── server
│ ├── build.gradle
│ └── src
│ └── com
│ └── server
│ ├── Application.java
│ ├── CustomerController.java
│ ├── CustomerRepository.java
│ └── model // works fine
│ └── Customer.java
├── build.gradle
I am using gradle sub-projects to manage the dependency which works fine at compile time.
But when I run the Application, Spring can't resolve the JPA annotations.
When I move the model class to the server project, it works fine.
Exception in thread "main" org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [...] Instantiation of bean failed;
[...]
Not an managed type: class com.model.Customer
root build.gradle
buildscript { ... }
allprojects {
repositories {
mavenCentral()
}
}
project(":android") { ... }
project(":model") {
apply plugin: "java"
}
project(":server") {
apply plugin: "java"
dependencies {
compile project(":model")
}
}
Is there a solution to include JPA models from a gradle sub-project ?
The reason is mostly to prevent duplicate code between the android and server appication
You Customer entity will not be found by default because it is not in a sub-pacakge of your Application class. Try using the #EntityScan annotation (see http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-separate-entity-definitions-from-spring-configuration).