Entities not scanned - spring-boot

I have a Maven project that represents the data layer of a single sign on (SSO) server. Other client applications shall rely on it for user authentication and authorization.
It is a .jar archive that shall be used by another REST project, also a Maven project.
Both are Spring Boot 2 based projects.
This project shall have some integration tests against the H2 and the MySQL databases.
As it is a library it does not run on its own. But it has some integration tests, that are to be executed. There is therefore no main class.
The command being used to build and execute the tests is mvn clean install -Denv="test"
My tree of source code looks like:
├── pom.xml
└── src
├── main
│   ├── java
│   │   └── com
│   │   └── thalasoft
│   │   └── userdata
│   │   ├── config
│   │   │   ├── DatabaseConfiguration.java
│   │   │   ├── JpaService.java
│   │   │   └── properties
│   │   │   ├── AbstractDatabaseProperties.java
│   │   │   ├── DatabaseH2TestProperties.java
│   │   │   ├── DatabaseMySQLAcceptanceProperties.java
│   │   │   ├── DatabaseMySQLPreProdProperties.java
│   │   │   ├── DatabaseMySQLProdProperties.java
│   │   │   ├── DatabaseMySQLTestProperties.java
│   │   │   ├── DatabaseOraclePreProdProperties.java
│   │   │   ├── DatabaseOracleProdProperties.java
│   │   │   ├── DatabaseOracleTestProperties.java
│   │   │   ├── DatabaseProperties.java
│   │   │   └── PropertyNames.java
│   │   ├── dialect
│   │   │   ├── CustomMySQL5InnoDBDialect.java
│   │   │   └── CustomOracle10gDialect.java
│   │   ├── exception
│   │   │   ├── CannotDeleteEntityException.java
│   │   │   ├── EnrichableException.java
│   │   │   ├── EntityAlreadyExistsException.java
│   │   │   ├── EntityNotFoundException.java
│   │   │   └── NoEntitiesFoundException.java
│   │   ├── jpa
│   │   │   ├── domain
│   │   │   │   ├── AbstractEntity.java
│   │   │   │   ├── EmailAddress.java
│   │   │   │   ├── User.java
│   │   │   │   └── UserRole.java
│   │   │   └── repository
│   │   │   ├── GenericRepositoryImpl.java
│   │   │   ├── GenericRepository.java
│   │   │   ├── UserRepositoryCustom.java
│   │   │   ├── UserRepositoryImpl.java
│   │   │   ├── UserRepository.java
│   │   │   ├── UserRoleRepositoryCustom.java
│   │   │   ├── UserRoleRepositoryImpl.java
│   │   │   └── UserRoleRepository.java
│   │   └── service
│   │   ├── UserRoleServiceImpl.java
│   │   ├── UserRoleService.java
│   │   ├── UserServiceImpl.java
│   │   └── UserService.java
│   └── resources
│   ├── application.properties
│   └── custom
│   └── typedef.hbm.xml
└── test
├── java
│   └── com
│   └── thalasoft
│   └── userdata
│   ├── assertion
│   │   └── UserAssert.java
│   ├── it
│   │   ├── jpa
│   │   │   ├── AbstractRepositoryTest.java
│   │   │   ├── UserRepositoryTest.java
│   │   │   └── UserRoleRepositoryTest.java
│   │   └── service
│   │   ├── AbstractServiceTest.java
│   │   └── UserServiceTest.java
│   └── ut
│   ├── AbstractRepositoryTest.java
│   └── UserRepositoryTest.java
└── resources
├── h2
│   └── data-source-test.properties
├── mysql
│   ├── clean-up-before-each-test.sql
│   └── data-source-test.properties
└── oracle
├── data-source-preprod.properties
└── data-source-test.properties
The DatabaseH2TestProperties is loaded thanks to a custom annotation define in another Maven toolbox project:
#EnvTest
#DbH2
#Configuration
#PropertySource({ "classpath:h2/data-source-test.properties" })
public class DatabaseH2TestProperties extends AbstractDatabaseProperties {
private static Logger logger = LoggerFactory.getLogger(DatabaseH2TestProperties.class);
public DatabaseH2TestProperties() {
logger.debug("===========>> Loading the classpath h2/data-source-test.properties file");
}
}
The data-source-test.properties file contains:
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.datasource.driver-class-name=net.sf.log4jdbc.DriverSpy
spring.datasource.url=jdbc:log4jdbc:h2:file:./target/useraccounttest
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.show-sql=true
The tests all are based on the class:
#ContextConfiguration(classes = { DatabaseConfiguration.class })
#RunWith(SpringRunner.class)
#Sql(executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, scripts = { "classpath:mysql/clean-up-before-each-test.sql" })
public abstract class AbstractRepositoryTest {
}
On this class, I wonder if I should not use #SpringBootTest(classes = { DatabaseConfiguration.class }) instead.
And the configuration is done with:
#EnableAutoConfiguration
#ComponentScan(nameGenerator = PackageBeanNameGenerator.class, basePackages = { "com.thalasoft.userdata" })
public class DatabaseConfiguration {
}
The connection to the H2 database is successful:
02:23:56.299 [main] DEBUG jdbc.audit - 100. Connection.getMetaData() returned dbMeta74: conn99: url=jdbc:h2:file:./target/useraccounttest user=SA com.zaxxer.hikari.pool.ProxyConnection.getMetaData(ProxyConnection.java:361)
02:23:56.299 [main] DEBUG org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator - Database ->
name : H2
version : 1.4.197 (2018-03-18)
major : 1
minor : 4
02:23:56.299 [main] DEBUG org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator - Driver ->
name : H2 JDBC Driver
version : 1.4.197 (2018-03-18)
major : 1
minor : 4
02:23:56.299 [main] DEBUG org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator - JDBC version : 4.0
02:23:56.299 [main] INFO org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
02:23:56.305 [main] DEBUG jdbc.audit - 100. Connection.clearWarnings() returned com.zaxxer.hikari.pool.ProxyConnection.close(ProxyConnection.java:250)
But I get an excetpion.
What the console log has to say:
02:23:56.338 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
02:23:56.338 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'com.thalasoft.userdata.config.JpaService'
02:23:56.338 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'com.thalasoft.userdata.config.properties.DatabaseH2TestProperties'
02:23:56.338 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'com.thalasoft.userdata.jpa.repository.GenericRepositoryImpl'
02:23:56.338 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'com.thalasoft.userdata.jpa.repository.GenericRepositoryImpl'
02:23:56.338 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
02:23:56.340 [main] WARN org.springframework.context.support.GenericApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.thalasoft.userdata.jpa.repository.GenericRepositoryImpl' defined in file [/home/stephane/dev/java/projects/user-data/target/classes/com/thalasoft/userdata/jpa/repository/GenericRepositoryImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.Class<?>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Indeed, I have a custom generic repository:
#Repository
#Transactional
public class GenericRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>
implements GenericRepository<T, ID> {
private EntityManager entityManager;
private final Class<T> domainClass;
public GenericRepositoryImpl(Class<T> domainClass, EntityManager entityManager) {
super(domainClass, entityManager);
this.entityManager = entityManager;
this.domainClass = domainClass;
}
public EntityManager getEntityManager() {
return entityManager;
}
}
#NoRepositoryBean
public interface GenericRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
public EntityManager getEntityManager();
}
And it is used as:
public interface UserRepository extends GenericRepository<User, Long>, UserRepositoryCustom {
}
public interface UserRepositoryCustom {
public User deleteByUserId(Long id) throws EntityNotFoundException;
}
public class UserRepositoryImpl implements UserRepositoryCustom {
#Autowired
private UserRepository userRepository;
}
It feels like the domain class cannot be found for the generic type.

Your GenericRepository interface and GenericRepositoryImpl class fit the pattern for repository fragment used in custom repository implementations in Spring Data JPA, so my guess is that Spring Data is trying to instantiate it for use as such. I would try renaming GenericRepositoryImpl to AbstractGenericRepository or making it an abstract class or perhaps both. You could also try removing #Repository annotation - after all class GenericRepositoryImpl is not a repository, but rather a base for implementing one.
Edit:
From your code it seems you're using the GenericRepository to create repository with custom method for eleting user by id. That being said I belive this code would be sufficient:
public interface UserRepository extends JpaRepository<User, Long> {
void deleteByUserId(Long id);
}
and if field userId in your User class is the one annotated as entity id, you do not even need the custom method since JpaRepository extends CrudRepository, which already has method deleteById(ID id).

Related

JSPs with Spring Boot

I have been working on a spring-boot project initialized with spring initialzr. The generated package has no /webapp directory, hence had to add /webapp directory. I have read from spring documentation that spring detects static files from /static,resources. I have placed 3 different index.jsp to test which one gets displayed by my controller. Below are the code snippets.
Directory Tree:
├── HELP.md
├── mvnw
├── mvnw.cmd
├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │   └── databasedisplay
│   │   │   └── app
│   │   │   ├── AppApplication.java
│   │   │   ├── config
│   │   │   │   ├── WebAppInitializer.java
│   │   │   │   └── WebConfig.java
│   │   │   ├── controller
│   │   │   │   ├── HomeController.java
│   │   │   │   └── IndexController.java
│   │   │   ├── repository
│   │   │   └── ServletInitializer.java
│   │   ├── resources
│   │   │   ├── application.properties
│   │   │   ├── index.jsp
│   │   │   ├── static
│   │   │   │   └── index.jsp
│   │   │   └── templates
│   │   └── webapp
│   │   └── WEB-INF
│   │   └── views
│   │   └── index.jsp
│   └── test
│   └── java
│   └── com
│   └── databasedisplay
│   └── app
│   └── AppApplicationTests.java
└── target
├── classes
│   ├── application.properties
│   ├── com
│   │   └── databasedisplay
│   │   └── app
│   │   ├── AppApplication.class
│   │   ├── config
│   │   │   ├── WebAppInitializer.class
│   │   │   └── WebConfig.class
│   │   ├── controller
│   │   │   ├── HomeController.class
│   │   │   └── IndexController.class
│   │   └── ServletInitializer.class
│   ├── index.jsp
│   └── static
│   └── index.jsp
├── generated-sources
│   └── annotations
├── generated-test-sources
│   └── test-annotations
├── maven-status
│   └── maven-compiler-plugin
│   ├── compile
│   │   └── default-compile
│   │   ├── createdFiles.lst
│   │   └── inputFiles.lst
│   └── testCompile
│   └── default-testCompile
│   ├── createdFiles.lst
│   └── inputFiles.lst
└── test-classes
└── com
└── databasedisplay
└── app
└── AppApplicationTests.class
index.jsp (in '/resources')
<html>
<head></head>
<body>
<h1>This is the body of the sample view in /resources</h1>
</body>
index.jsp (in '/static')
<html>
<head></head>
<body>
<h1>This is the body of the sample view in /static</h1>
</body>
</html>
index.jsp (in '/WEB-INF/views/')
<html>
<head></head>
<body>
<h1>This is the body of the sample view in WEB-INF/views</h1>
</body>
</html>
Controller
#Controller
public class IndexController {
#RequestMapping(value = "/indexA", method = RequestMethod.GET)
public String index() {
return "index";
}
}
Configuration Classes
WebConfig.java
#Configuration
#EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
#Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver resolver
= new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
#Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable("testServlet");
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/").setCachePeriod(3600)
.resourceChain(true).addResolver(new PathResourceResolver());
}
}
WebInitializer.java
public class WebAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.scan("com.databasedisplay.app");
container.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = container.addServlet("mvc", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
The issue is when I run with mvn spring-boot:run or mvn clean package spring-boot:run the \target directory as shown in the directory tree has no index.jsp from \WEB-INF\views\ (in fact the target directory doesn't have a WEB-INF directory at all). But I still get the following output when I curl http://localhost:8080/indexA :
This is the body of the sample view in WEB-INF/views
Can someone explain how the view resolver even maps the view names to the corresponding views? (I have looked into InternalResourceViewResolver and how to set prefixes and suffixes but that still does not explain how it can render a jsp when it is not in target)
Can someone point out to the differences between mvn spring-boot:run and mvn clean package spring-boot:run as in the latter there is WEB-INF directory in the target.
Why am I getting index.jsp corresponding to /WEB-INF but not other views on curl?
JSP's are part of legacy Java Enterprise applications and are not the core of Spring Boot/MVC and it's more modern Template Engine approach (although Spring is based on Java EE). If you have any good reason to use JSP's, it could work. But with Spring, the MVC approach/implementation is to use the more modern template engines with technologies like Thymeleaf, FreeMarker, Groovy Markup, and Mustache.
Question 1 If you have configured your pom.xml correctly, you can use different starters to configure how your application is deployed/run. JSP's are not a standard solution for Spring and should be configured seperately, it needs to be configured so that it will compile the JSP's into their respective location so that Tomcat reads it from the webapps folder. To compile and render JSP's your pom.xml needs both spring-boot-starter-web and tomcat-embed-jasper including the tag <scope>provided</scope>.
Question 2 Spring comes with an embedded Tomcat server (spring-boot-starter-web). When you run mvn spring-boot:run it will start a Tomcat server and deploy your Spring Boot application on the Tomcat localhost:8080. mvn clean, before spring-boot:run, just deletes the output of a build by deleting the build directory.
Question 3 Each .HTML template or .JSP file have their respective location in the project before compiling, so therefore some .JSP's are not compiled in your folders.
A Java Enterprise application and it's corresponding JSP's use a different project structure than Spring: All JSP's will be compiled from the "src/main/webapp/WEB-INF/jsp/" if you have the right dependencies and run spring-boot:run. If you manually create a project, through compiling by cmd -jar, you should include your JSP's in the "/webapp/" folder and the Java.classes in WEB-INF/classes/MyServlet.class.
By using, for instance Thymeleaf (spring-boot-starter-thymeleaf), if you build your artifacts the IDE will compile templates from /resources/templates and work from there on your MVC project, where you can integrate your REST controllers seamlessly.
Tomcat stays pivotal in how your enterprise application is deployed, only that you need to adjust your project in Spring so that it will map and compile the right files into the .WAR before deploying.
My advice would be, for MVC, to use the template engines instead of the legacy JSP's. of course, there will use cases for JSP's inside a Spring project but it requires a differect structure and dependencies.

SAP Hybris extend Backoffice - Spring bean overwrite

I am trying to overwrite an backoffice class which has a bean, but it is in a web context.
In our project we have already an custom backoffice package, but there is no spring.xml. Also no other classes in that package have any beans.
To be more specific, I am trying to overwrite this class: hybris/bin/ext-backoffice/backoffice/web/webroot/WEB-INF/classes/com/hybris/backoffice/widgets/searchadapters/conditions/products/FlexibleSearchUncategorizedConditionAdapter.class.
Our backoffice extension looks like that:
├── backoffice <-- webroot
│   ├── resources
│   │   └── widgets
│   │   ├── projectbackofficeWidget
│   │   │   ├── definition.xml
│   │   │   ├── images
│   │   │   │   └── ...
│   │   │   ├── labels
│   │   │   │   └── ...
│   │   │   ├── projectbackofficewidget.scss
│   │   │   └── projectbackofficewidget.zul
│   │   └── actions
│   │   └── ...
│   ├── src
│   │   └── de
│   │   └── company
│   │   └── project
│   │   └── backoffice
│   │   ├── b2bcommerce
│   │   │   └── actions
│   │   │   └── ...
│   │   ├── editors
│   │   │   └── ...
│   │   ├── services
│   │   │   └── ...
│   │   └── widgets
│   │   ├── ...
│   │   └── searchadapters
│   │   └── myFlexibleSearchUncategorizedConditionAdapter.java
│   └── testsrc
│   └── ...
├── build.xml
├── buildcallbacks.xml
├── extensioninfo.xml
├── extensioninfo.xsd
├── gensrc
│   └── ...
├── platformhome.properties
├── project.properties
├── resources
│   ├── backoffice
│   │   └── projectbackoffice_bof.jar
│   ├── beans.xsd
│   ├── cockpitng
│   │   └── ...
│   ├── items.xsd
│   ├── projectbackoffice
│   │   ├── projectbackoffice-testclasses.xml
│   │   └── projectbackoffice-webtestclasses.xml
│   ├── projectbackoffice-backoffice-config.xml
│   ├── projectbackoffice-backoffice-labels
│   │   └── ...
│   ├── projectbackoffice-backoffice-spring.xml
│   ├── projectbackoffice-backoffice-widgets.xml
│   ├── projectbackoffice-beans.xml
│   ├── projectbackoffice-items.xml
│   ├── projectbackoffice-spring.xml
│   ├── projectbackoffice.build.number
│   └── localization
│   └── ...
├── src
│   └── de
│   └── company
│   └── project
│   └── backoffice
│   ├── projectbackofficeStandalone.java
│   ├── constants
│   │   └── projectbackofficeConstants.java
│   └── jalo
│   └── projectbackofficeManager.java
└── testsrc
└── ...
I know there is an spring.xml, but it is not working with the classes in the webroot.
In all other web extensions, there are separated files for that.
How do I add an spring.xml so I can overwrite that OOTB bean? Or how can I use the existing spring.xml for that?
You can use customize for that, but it seems there is a better solution that lets you append the backoffice web spring configs as mentioned here.

No mapping found for HTTP request with URI [/welcome] in DispatcherServlet with name 'dispatcherServlet' in Spring Boot 1.5.3v

Am new to spring boot unable to get the issue resolved.
In below Screenshots i have commented "/hello" which i could access with localhost:1200/hello .But unable to access other controllers as "/welcome" ,"/home" attached screenshots .
SpringApplication class
Controller class
Since your #SpringBootApplication annotation is in com.example.demo, and no basePackage is defined for scanning, it will only scan that package and its nested packages. The easiest way to solve this is to move your controller package.
From this:
.
└── main
   ├── java
   │   └── com
   │   └── example
   │   ├── controller
   │   │   └── DemoRestController.java
   │   └── demo
   │   └── DemoApplication.java
   └── resources
   └── application.properties
To this:
.
└── main
   ├── java
   │   └── com
   │   └── example
   │   └── demo
   │   ├── controller
   │   │   └── DemoRestController.java
   │   └── DemoApplication.java
   └── resources
   └── application.properties
Doc from #ComponentScan :
Either basePackageClasses() or basePackages() (or its alias value())
may be specified to define specific packages to scan. If specific
packages are not defined, scanning will occur from the package of the
class that declares this annotation.

How should the gradle build scripts be to modularize this application?

I am trying to apply an example from the book Gradle in Action to learn how to separate a gradle application into subprojects. I did the example in the book and everything worked out fine.
I decided to apply the same concepts to a sample application from the Griffon Framework called minimalistic build, source code: sources. I selected this application because it follows the normal application structure instead of Griffon's, and I was trying to fill the gap (IMHO) in Griffon's documentation for multi project builds: it has one exaple that uses Open-Dolphin, Swing, JavaFX, Servlets that I felt it was too complicated to learn the basics.
Of course I hit the wall big time, multiple times...
Griffon's JavaFX application has the following structure:
├── build.gradle
├── config
│   └── HEADER
├── gradle
│   ├── functional-test.gradle
│   ├── integration-test.gradle
│   ├── javafx-plugin.gradle
│   └── wrapper
│   ├── gradle-wrapper.jar
│   └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── src
├── functional-test
│   └── java
│   └── org
│   └── example
│   └── SampleFunctionalTest.java
├── integration-test
│   └── java
│   └── org
│   └── example
│   └── SampleIntegrationTest.java
├── main
│   ├── java
│   │   ├── Config.java
│   │   └── org
│   │   └── example
│   │   ├── Launcher.java
│   │   ├── SampleController.java
│   │   ├── SampleModel.java
│   │   ├── SampleService.java
│   │   └── SampleView.java
│   └── resources
│   ├── application.properties
│   ├── griffon-icon-128x128.png
│   ├── griffon-icon-16x16.png
│   ├── griffon-icon-24x24.png
│   ├── griffon-icon-256x256.png
│   ├── griffon-icon-32x32.png
│   ├── griffon-icon-48x48.png
│   ├── griffon-icon-64x64.png
│   ├── griffon.png
│   ├── log4j.properties
│   ├── messages.properties
│   ├── META-INF
│   │   └── griffon
│   │   ├── griffon.core.artifact.GriffonController
│   │   ├── griffon.core.artifact.GriffonModel
│   │   ├── griffon.core.artifact.GriffonService
│   │   └── griffon.core.artifact.GriffonView
│   ├── org
│   │   └── example
│   │   └── sample.fxml
│   └── resources.properties
└── test
└── java
└── org
└── example
├── SampleControllerTest.java
└── SampleServiceTest.java
The build.gradle file content is:
// tag::plugins[]
plugins {
id 'java'
id 'idea'
id 'com.github.ben-manes.versions' version '0.12.0'
id 'com.github.hierynomus.license' version '0.11.0'
}
apply from: 'gradle/javafx-plugin.gradle'
apply from: 'gradle/integration-test.gradle'
apply from: 'gradle/functional-test.gradle'
// end::plugins[]
// tag::javafx[]
javafx {
mainClass = 'org.example.Launcher'
}
// end::javafx[]
// tag::dependencies[]
repositories {
jcenter()
mavenLocal()
}
dependencies {
compile "org.codehaus.griffon:griffon-javafx:${griffonVersion}"
compile "org.codehaus.griffon:griffon-guice:${griffonVersion}"
runtime('log4j:log4j:1.2.17') {
exclude group: 'ant', module: 'ant-nodeps'
exclude group: 'ant', module: 'ant-junit'
exclude group: 'ant-contrib', module: 'ant-contrib'
}
runtime 'org.slf4j:slf4j-log4j12:1.7.21'
testCompile "org.codehaus.griffon:griffon-javafx-test:${griffonVersion}"
testCompile 'pl.pragmatists:JUnitParams:1.0.5'
testCompile 'org.mockito:mockito-core:2.0.59-beta'
}
// end::dependencies[]
// tag::resources[]
processResources {
from(sourceSets.main.resources.srcDirs) {
exclude '**/*.properties'
exclude '**/*.xml'
}
from(sourceSets.main.resources.srcDirs) {
include '**/*.properties'
include '**/*.xml'
filter(org.apache.tools.ant.filters.ReplaceTokens, tokens: [
'application.name' : project.name,
'application.version': project.version,
'griffon.version' : griffonVersion
])
}
}
// end::resources[]
license {
header = rootProject.file('config/HEADER')
strictCheck = true
ignoreFailures = true
mapping {
java = 'SLASHSTAR_STYLE'
fxml = 'XML_STYLE'
}
ext.year = '2016'
exclude '**/*.png'
}
And the structure I was trying to achieve is:
├── build.gradle
├── config
│   └── HEADER
├── gradle
│   ├── functional-test.gradle
│   ├── integration-test.gradle
│   ├── javafx-plugin.gradle
│   └── wrapper
│   ├── gradle-wrapper.jar
│   └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── launcher
│   ├── launcher-build.gradle
│   └── src
│   └── main
│   └── java
│   ├── Config.java
│   └── org
│   └── example
│   └── Launcher.java
├── resources
│   ├── resources-build.gradle
│   └── src
│   └── main
│   └── resources
│   ├── application.properties
│   ├── griffon-icon-128x128.png
│   ├── griffon-icon-16x16.png
│   ├── griffon-icon-24x24.png
│   ├── griffon-icon-256x256.png
│   ├── griffon-icon-32x32.png
│   ├── griffon-icon-48x48.png
│   ├── griffon-icon-64x64.png
│   ├── griffon.png
│   ├── log4j.properties
│   ├── messages.properties
│   └── resources.properties
├── service
│   ├── resources
│   │   └── META-INF
│   │   └── griffon
│   │   └── griffon.core.artifact.GriffonController
│   ├── service-build.gradle
│   └── src
│   ├── main
│   │   └── java
│   │   └── org
│   │   └── example
│   │   └── SampleService.java
│   └── test
│   └── java
│   └── org
│   └── example
│   └── SampleServiceTest.java
├── settings.gradle
└── view
├── src
│   ├── functional-test
│   │   └── java
│   │   └── org
│   │   └── example
│   │   └── SampleFunctionalTest.java
│   ├── integration-test
│   │   └── java
│   │   └── org
│   │   └── example
│   │   └── SampleIntegrationTest.java
│   ├── main
│   │   ├── java
│   │   │   └── org
│   │   │   └── example
│   │   │   ├── SampleController.java
│   │   │   ├── SampleModel.java
│   │   │   └── SampleView.java
│   │   └── resources
│   │   ├── META-INF
│   │   │   └── griffon
│   │   │   ├── griffon.core.artifact.GriffonModel
│   │   │   ├── griffon.core.artifact.GriffonService
│   │   │   └── griffon.core.artifact.GriffonView
│   │   └── org
│   │   └── example
│   │   └── sample.fxml
│   └── test
│   └── java
│   └── org
│   └── example
│   └── SampleControllerTest.java
└── view-build.gradle
I don't know if that structure is the one that makes more sense, but is the one I first thought of.
Regardless everything I tried I could not build this project and I am wondering if anyone could tell me if I made a mistake with the selection of the subprojects and what should be the content for the build files.
I created a zip file with the rearranged source here keeping the original build.gradle file untouched, with a settings.gradle file that makes Gradle properly recognize the new structure.
Thanks!
The problem is caused by missing resource files in the service project. You'll find a similar problem in the view project. This is is because all resource files were moved to another location (the resources project). There was no problem before splitting the application into subprojects because all resources were at the right place.
You can fix the build by following these steps:
$ cd service
$ mkdir -p src/test/resources
$ touch src/test/resources/Config.properties
$ mkdir -p src/main/resources
$ mv ../resources/src/main/resources/messages.properties src/main/resources/
$ cd ../view
$ mkdir -p src/test/resources
$ touch src/test/resources/Config.properties
This should be enough to make the tests green again.
Marcelo,
I've posted a new version of the multi-project build here. This version keeps common setup at the root level, leaving what's specific to each subproject on each subproject's build file.

View template solve error in Spring MVC

I have PostController using Spring MVC to manage all posts and render all templates under folder admin/posts/. For example admin/posts/new.jade.
#RequestMapping(value = "new")
public String newPost(Model model){
model.addAttribute("postForm", new PostForm());
return "admin/posts/new";
}
Returning admin/posts/new will cause an error and the template new.jade cannot be found. So I'm using return admin/posts_new instead and it' ok.
However I wanna use return admin/posts/new to keep templates separated.
Can anyone help me fix it?
Here is the templates structure. webapp/views is my templates root directory.
webapp
| ├── views
│   ├── admin
│   │   ├── home
│   │   ├── index.jade
│   │   ├── layout
│   │   │   ├── admin.jade
│   │   │   ├── footer.jade
│   │   │   ├── head.jade
│   │   │   └── navbar.jade
│   │   ├── posts
│   │   │   └── new.jade
│   │   ├── posts_edit.jade
│   │   ├── posts_index.jade
│   │   ├── posts_new.jade
│   │   └── settings.jade
│   ├── home
│   │   ├── about.jade
│   │   └── index.jade
│   ├── layout
│   │   ├── app.jade
│   │   ├── footer.jade
│   │   ├── head.jade
│   │   ├── navbar.jade
│   │   └── top.jade
│   ├── posts
│   │   ├── archive.jade
│   │   ├── index.jade
│   │   └── show.jade
│   └── users
│   └── signin.jade

Resources