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).
Related
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
First Thing to say, I am a relatively inexperienced programmer.
My task is to import a given gradle project into Spring Boot Tool Suite (sts). I have already download springboot cli, java, gradle. & In the past, I was able to run spring perfectly on another project, unfortunately I had to get my hard drive replaced, so I lost a considerable amount of downloads.
Nonetheless, my issue is two-parted. Firstly, my tool suite (ide? It's basically eclipse) does not recognize my project as a a java project, I have tried many options & the only was to fix that portion is to hardcode org.eclipse.core.javabuilder within the buildCommand tag in my .project file, which I don't remember doing for my last project.
Here is the directory tree of the backend folder(don't concern with the frontend)
.
├── build.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
├── main
│ ├── java
│ │ └── ca
│ │ └── mcgill
│ │ └── ecse321
│ │ └── eventregistration
│ │ ├── EventRegistrationApplication.java
│ │ ├── controller
│ │ │ ├── ApiError.java
│ │ │ ├── EventRegistrationRestController.java
│ │ │ └── RestExceptionHandler.java
│ │ ├── dao
│ │ │ ├── EventRegistrationRepository.java
│ │ │ ├── EventRepository.java
│ │ │ ├── PersonRepository.java
│ │ │ └── RegistrationRepository.java
│ │ ├── dto
│ │ │ ├── EventDto.java
│ │ │ ├── PersonDto.java
│ │ │ └── RegistrationDto.java
│ │ ├── model
│ │ │ ├── Event.java
│ │ │ ├── Person.java
│ │ │ ├── Registration.java
│ │ │ └── RegistrationManager.java
│ │ └── service
│ │ └── EventRegistrationService.java
│ └── resources
│ └── application.properties
└── test
└── java
└── ca
└── mcgill
└── ecse321
└── eventregistration
└── service
├── event
│ └── TestCinema.java
├── payment
│ ├── TestPaymentWithCreditCard.java
│ ├── TestPaymentWithCreditCardData.java
│ └── TestUtils.java
└── role
├── PromoterRoleTestData.java
└── TestPromoterRole.java
Additionally, Here it my build.gradle file
buildscript {
ext {
springBootVersion = '2.1.2.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
runtimeOnly 'org.postgresql:postgresql'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
This fixes my java problem, but I still cannot get it running as a spring boot application.
Please help as I am not sure where to continue!!! I need to be able to run this project as a spring boot application for backend services, as I will then be tasked with connecting it to frontend services with vue.js. (Don't worry i got that part)!
Here is my EventRegistration.java file as well
package ca.mcgill.ecse321.eventregistration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.SpringApplication;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
#RestController
#SpringBootApplication
public class EventRegistrationApplication {
public static void main(String[] args) {
SpringApplication.run(EventRegistrationApplication.class, args);
}
#RequestMapping("/")
public String greeting() {
return "ECSE321 Event Registration Application - Backend base URL.\n"
+ "Use the API methods to interact with the backend!";
}
}
Though I stopped using eclipse but following used to solve situations like this
1.
- Eclipse ->preferences-->java-->installed JRE --> select a standard vm
(can find here jdk1.8.0_51.jdk/Contents/Home)
2.
- add the JRE System Library to your project build path
- right click project > select build path > libraries >
- if JRE is listed then good otherwise > add Library
- select JRE library and finish
I'm having a simple Java single module Gradle project in which I use Mapstruct for the Java mapping. My build.gradle looks like this:
plugins {
id 'java-library'
id 'groovy'
id 'net.ltgt.apt' version '0.20'
}
repositories {
jcenter()
}
dependencies {
implementation 'org.mapstruct:mapstruct-jdk8:1.2.0.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.2.0.Final'
testImplementation 'org.codehaus.groovy:groovy-all:2.5.5'
// Use the awesome Spock testing and specification framework even with Java
testImplementation 'org.spockframework:spock-core:1.2-groovy-2.5'
testImplementation 'junit:junit:4.12'
}
sourceSets {
main {
java {
srcDirs "${project.buildDir}/generated/sources/annotationProcessor/java/main"
}
}
test {
java {
srcDirs "${project.buildDir}/generated/sources/annotationProcessor/java/test"
}
}
}
My source folder contains the following Java source code:
src
├── main
│ ├── java
│ │ └── ch
│ │ └── silviowangler
│ │ ├── Person.java
│ │ ├── SomeMapper.java
│ │ └── User.java
│ └── resources
└── test
├── groovy
│ └── ch
│ └── silviowangler
├── java
│ └── ch
│ └── silviowangler
│ └── YoloMapper.java
└── resources
SomeMapper is a simple mapper interface that looks like this
#Mapper
public interface SomeMapper {
#Mappings({
#Mapping(target = "firstName", source = "nickname"),
#Mapping(target = "surname", ignore = true),
#Mapping(target = "dateOfBirth", ignore = true)
})
Person fromString(User user);
}
And the YoloMapper that resides in the test scope looks like that
#Mapper
public interface YoloMapper {
String fromLocalDate(LocalDate localDate);
}
When I run ./gradlew clean cTJ the build completes successfully and the annotation processor generates a mapper implementation for SimpleMapper but it does not generate anything for the YoloMapper. The build folder after the build looks like
build
├── classes
│ └── java
│ ├── main
│ │ └── ch
│ │ └── silviowangler
│ │ ├── Person.class
│ │ ├── SomeMapper.class
│ │ ├── SomeMapperImpl.class
│ │ └── User.class
│ └── test
│ └── ch
│ └── silviowangler
│ └── YoloMapper.class
├── generated
│ └── sources
│ └── annotationProcessor
│ └── java
│ ├── main
│ │ └── ch
│ │ └── silviowangler
│ │ └── SomeMapperImpl.java
│ └── test
└── tmp
├── compileJava
└── compileTestJava
How can I make Gradle to tell the annotation processor to generate Mapstruct mapper implementation in the test scope?
You need to configure the testAnnocationProcess configuration, as follows:
dependencies{
// for Main sources set
implementation 'org.mapstruct:mapstruct-jdk8:1.2.0.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.2.0.Final'
// for Test sources set
testAnnotationProcessor "org.mapstruct:mapstruct-processor:1.2.0.Final"
}
I have a Spring project with the following structure:
.
├── pom.xml
├── core-module
│ ├── pom.xml
│ └── src
│ ├── main
│ │ ├── java
│ │ └── resources
│ │ ├── applicationContext.xml
│ │ └── file.xml
│ └── test
│ ├── java
│ └── resources
│ ├── file.xml
│ └── foo.xml
└── web-module
├── pom.xml
└── src
├── main
│ └── java
└── test
└── java
In my applicationContext.xml file, I have the following import:
<import resource="classpath:file.xml" />
In production I want to use the file.xml defined in main, and during tests I want to use the one defined in the test folder; it's actually what is happenning when I run the tests of the core-module.
However, when I run the tests of the web-module, this is not the case, the file used is the one of the main folder.
How to perform what I want?
Some notes:
web-module has a test-jar dependency to core-module, so tests resources are included;
if I go inside the target directory, the file.xml is the good one in the test-classes folder;
when running web-module tests, if I put a breakpoint in the Spring code, then a getClass().getClassLoader().getResource() on file.xml returns the one defined in main, but if I run the same method on the foo.xml file it returns me the only one available in the test folder, so both files seems to be present, but it acts as if the main takes over the test resource...
Thank you!
I'm using IntelliJ to develop a java application but I'm not able to import any of the packages I created. I marked my src folder as Sources Root and the tree suggests I'm able to import a package by just
import service.RMI;
on my App.java file.
but when I try to compile
javac App.java
I get an error saying
App.java:4: error: package service does not exist
import service.RMI;
^
Does anyone knows why this happens? Does it have to do with my project skeleton?
For a better understanding, I leave my project tree:
.
├── algorithms
│ └── SHA256.java
├── app
│ ├── App.class
│ └── App.java
├── file
│ ├── ChunkFile.java
│ └── Chunk.java
├── filesystem
│ └── filesystem.java
├── META-INF
│ └── MANIFEST.MF
├── peer
│ ├── listeners
│ │ ├── MClistener.java
│ │ └── MDBlistener.java
│ └── Peer.java
├── protocols
│ ├── Backup.java
│ ├── Delete.java
│ └── Restore.java
└── service
└── RMI.java
I found the solution.
I was compiling all wrong. I was trying to run
javac App.java
on my app directory but I figured out that I need to run
javac app/App.java
on my root directory - src, and then, to run the app I need
java app.App
Thanks for the kind replies.
Regards