Dependency management in gradle with mavenBom - spring

I have a java library that is imported in gradle like this
sourceControl {
gitRepository("git#github.com/mytest/commonslib.git") {
producesModule("com.lib:commonslib")
}
}
the lib contains a pom.xml with all dependencies.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lib</groupId>
<artifactId>commonslib</artifactId>
<version>0.1.10</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.7.5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
...
now i would like to import this pom to handle the dependend libraries.
But it does not work when i used it like this.
dependencyManagement {
imports {
mavenBom 'com.lib:commonslib:0.1.10'
}
}
I got the error: Could not resolve commonslib.pom (project :commonslib). Any hint whats wrong? Is it even possible to use producesModule and mavenBom in compbination?

Related

Maven dependency provided on submodule ear throws ClassNotFoundException

Environment:
Java 11
JBoss 7.2
Maven 3.5
I am getting this ERROR java.lang.ClassNotFoundException: net.sf.jasperreports.engine.JRException when I try to execute a method from a class in app-commons module. Jasper dependency in app-commons is compiled and app-commons dependency in app-back is provided.
How could I solve this?
Error
09:29:24,013 SEVERE [org.primefaces.application.exceptionhandler.PrimeExceptionHandler] (default task-1) net/sf/jasperreports/engine/JRException: java.lang.NoClassDefFoundError: net/sf/jasperreports/engine/JRException
...
Caused by: java.lang.ClassNotFoundException: net.sf.jasperreports.engine.JRException from [Module "deployment.accfor2.ear" from Service Module Loader]
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:255)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:410)
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398)
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:116)
... 78 more
Modules:
app (pom)
app-ear
app-back
app-commons (provided)
app-front
app-commons (provided)
app-commons
jasperreports (compiled)
...
pom.xml (app-commons)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.name.app</groupId>
<artifactId>app</artifactId>
<version>8.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>app-commons</artifactId>
<packaging>jar</packaging>
<name>app-commons</name>
...
<dependencies>
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>6.15.0</version>
</dependency>
</dependencies>
...
ReportManager.java (app-commons)
public class ReportManager {
...
public static void addParam(Map<String, Object> params, String nom, byte[] compiledReport) throws ReportException {
try {
params.put(nom, SerializationUtils.deserialize(compiledReport));
} catch (Exception e) {
throw new ReportException("Error deserialize compiledReport.");
}
}
...
pom.xml (app-back)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.name.app</groupId>
<artifactId>app</artifactId>
<version>8.0.0</version>
</parent>
<artifactId>app-back</artifactId>
<packaging>war</packaging>
<name>app-back</name>
<description>Módul back (intranet)</description>
<dependencies>
...
<dependency>
<groupId>com.name.app</groupId>
<artifactId>app-commons</artifactId>
<scope>provided</scope>
</dependency>
...
ExecuteReportBean.java (app-back)
public class ExecuteReportBean.java
...
public void compileReport(Informe informe, Map<String, Object> parametresSend) {
ReportManager.compilaReport(parametre.getJasperReport());//ERROR java.lang.ClassNotFoundException: net.sf.jasperreports.engine.JRException
...
If you declare the dependency as provided, it will not be packaged into the WAR.
Either change the scope to compile or let the application server provide it (by e.g. putting it into a JBoss module).
Because of transitive dependencies are not included when dependency is provided, so I had to restructure the modules this way.
Modules:
app (pom)
app-ear
jasperreports (compiled) MOVED FROM APP-COMMONS
app-back
app-commons (provided)
app-front
app-commons (provided)
app-commons
...
I was not able to change app-commons dependency to compiled because it is dependent of app-front and app-back. In app-commons as compiled I have an #ApplicationScope class that it would produce ambiguous Beans pointing to the class in app-commons because of jakartaee context management.

Spring Boot doesn't load application.yml config or?

I have a simple main app:
// Application.java
package com.my.application;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication(scanBasePackages = "com.my")
public class Application
{
public static void main(String[] args)
{
SpringApplication.run(Application.class, args);
}
}
Just a class:
// TestClass.java
package com.my.application;
public class TestClass
{
public TestClass()
{
}
}
With config:
//ApplicationConfiguration
package com.my.configuration;
import com.my.application.TestClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
#Configuration
public class ApplicationConfiguration
{
#Autowired
Environment env;
#Bean TestClass getTestClass()
{
System.out.println(env.getProperty("test"));
return new TestClass();
}
}
this is my pom file:
// pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.my</groupId>
<artifactId>test</artifactId>
<version>1.3.0</version>
<packaging>pom</packaging>
<name>test</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.23</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
the application.yml file is just:
// src/main/resources/application.yml
test: 123
Property "test" always = null.
What I was wrong?
Tried with #Value, #ConfigurationProperties,
#EnableConfigurationProperties,
#PropertySource("classpath:src/main/resources/application.yml") annotations,
without the snakeyaml library,
with another spring-boot versions,
but result always the same.
It has to do with Maven - application.properties is not part of the build when you're using <packaging>pom</packaging> in your pom file - hence when you start the Application, the file is not there to be read.
Remove <packaging>pom</packaging> from your pom and you should be good to go.
try adding dependency org.springframework.boot:spring-boot-configuration-processor
I also faced the same issue. Tried lot of things, but it nothing worked.
In the end, when I added below dependency in pom, my application is able to read application.yml file.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>

Using #ControllerAdvice as a dependency for another project

I make a common project for listening Exceptions and use #ControllerAdvice with #ExceptionHandler
#ControllerAdvice(annotations = RestController.class)
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
#ExceptionHandler({Exception.class})
#ResponseStatus(value = HttpStatus.NOT_FOUND)
#ResponseBody
public ResponseEntity<ErrorResponse> notFound(Exception ex) {
return new ResponseEntity<>(
new ErrorResponse(ex.getMessage(), 404, "My Custom Message"), HttpStatus.NOT_FOUND);
}
}
without any #SpringBootApplication and main method to adding as dependency to my another project. my pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>spring-commons-rest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-commons-rest</name>
<description>for Listening Exceptions</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
after adding its dependency and #ComponentScan to another project, but its not working as Exception handling for response custom Error. I appreciated any help.
I found that was not about using #ComponentScan and with using #Import it will work so fine. but if anyone has any better solution or some guiding line I will appreciate that.
I've solved it by adding
#Order(Ordered.HIGHEST_PRECEDENCE)
to the ControllerAdvice class that you are importing.
In my case, there was another ControllerAdvice class in the downstream project that was taking priority over the one I was importing.

Jersey service not found with recent version

I wanted to test a simple "Hello World" jersey service using Maven and Tomcat (7.0) in Eclipse. Maven downloaded the most recent version 1.17, but everytime I try to access the page I retreive a 404. However after changing back to version 1.9 it works as expected. Did anything change between those version or am I missing something?
What I do is calling localhost:8080/rngservice/rest/hello which gives a 404 error when I'm using jersey versions beyond 9. Using version 9 however works as intended and returns the HTML page.
Any suggestions?
My code:
package service.test;
import javax.ws.rs.*;
#Path("/hello")
public class RNGResource {
#GET
#Produces(MediaType.TEXT_HTML)
public String getItHTML() {
return "<htm> <title> " + "Got it!" + "</title> </html>";
}
}
I don't use a web.xml but a PackagesResourceConfig for the servlet configuration
package service.test;
import javax.ws.rs.ApplicationPath;
import com.sun.jersey.api.core.PackagesResourceConfig;
#ApplicationPath("/rest/*")
public class RNGServiceApplication extends PackagesResourceConfig {
public RNGServiceApplication() {
super("service.test");
}
}
The Maven .pom
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>service</groupId>
<artifactId>rngservice</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>rngservice</name>
<build>
<!-- ... -->
</build>
<dependencies>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.17</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.17</version>
</dependency>
</dependencies>
</project>

Can find imported Spring beans from JAR, but not from WAR

My application consists of three Maven projects (I am omitting other modules)): FrameworkBase (JAR), FrameworkBaseImpl (JAR), FrameworkRestService (WAR).
FrameworkRestService is a plugin to FrameworkBaseImpl, drawing its class/interface definitions
from FrameworkBase, which FrameworkBaseImpl implements/extends. (I had to split FrameworkBase to avoid Maven curcular dependencies).
FrameworkBaseImpl has a main, which invokes Jetty, passing the FrameworkRestService war.
I am trying to have Spring inject a RestService instance as a field member in the (sole) instance of FrameworkMain class of FrameworkBaseImpl. My Spring points to FrameworkRestService class inside FrameworkRestService project as implementing the restService bean.
And here is the problem: Although Spring seems to find the imported framework_rest_service.context file in the WAR that contains the bean it fails injecting it (no bean named restService is found). But if I convert FrameworkRestService into a JAR - it magically succeeds! I am stuck for 2 days on it! Please help!
FrameworkBase pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>framework.base</artifactId>
<packaging>jar</packaging>
<name>framework.base</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<parent>
<groupId>controlapps</groupId>
<artifactId>controlapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../controlapp/pom.xml</relativePath>
</parent>
</project>
FrameworkBase RestService:
package com.company.controlapps.framework.base;
public class RestService {
public FrameworkMain frameworkMain;
/* Setters for Spring */
public void setFrameworkMain(FrameworkMain frameworkMain)
{this.frameworkMain = frameworkMain;}
}
FrameworkBase FrameworkMain:
package com.company.controlapps.framework.base;
public interface FrameworkMain {
...
}
FrameworkBaseImpl pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>framework.base.impl</artifactId>
<packaging>jar</packaging>
<name>framework.base.impl</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<parent>
<groupId>controlapps</groupId>
<artifactId>controlapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../controlapp/pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>controlapps</groupId>
<artifactId>framework.base</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>controlapps</groupId>
<artifactId>framework.restservice</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>runtime</scope>
<type>war</type>
</dependency>
</dependencies>
</project>
FrameworkBaseImpl FrameworkMainImpl:
package com.company.controlapps.framework.base.impl;
public class FrameworkMainImpl implements FrameworkMain {
....
protected RestService restService;
public void setRestService(RestService restService)
{this.restService = restService;}
}
public static void main(String[] args) {
context = new ClassPathXmlApplicationContext(SPRING_CONTEXT_FILENAME);
FrameworkMainImpl frameworkMain = (FrameworkMainImpl) context.getBean("frameworkMain");
...
}
FrameworkBaseImpl spring context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<import resource="classpath*:framework_restservice_context.xml"/>
<bean id="frameworkMain" class="com.company.controlapps.framework.base.impl.FrameworkMainImpl" >
<property name="restService" ref="restService" />
</bean>
</beans>
FrameworkRestService FrameworkRestService pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>framework.restservice</artifactId>
<packaging>war</packaging>
<name>framework.restservice</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jersey.version>1.12</jersey.version>
</properties>
<parent>
<groupId>controlapps</groupId>
<artifactId>controlapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../controlapp/pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>controlapps</groupId>
<artifactId>framework.base</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server-linking</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-spring</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.5.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
</project>
FrameworkRestService spring framework_restservice_context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="restService" class="com.radware.controlapps.framework.restservice.FrameworkRestService">
<property name="frameworkMain" ref="frameworkMain" />
</bean>
</beans>
FrameworkRestService FrameworkRestService.java snippet:
package com.company.controlapps.framework.restservice;
#Path("myresource")
public class FrameworkRestService extends RestService {
...
#Context
UriInfo uriInfo;
#Context
Request request;
#GET
#Produces(MediaType.APPLICATION_JSON)
public MyResource getMyResource() {
...
frameworkMain.doSomething();
....
}
Sorry for the long question. :-)
It wasn't a class loader issue. I had the WAR and the JAR use the same class loader (of the JAR). Somebody commented that I shouldn't have tried to link a WAR and look for beans in there.
So instead of trying to solve the problem I simply bypassed it by canceling Spring dependencies between the JAR and the WAR. In the WAR I still needed a reference to the FrameworkMain singleton instantiated in the JAR.
I "hacked" this as follows: I added a class named Holder with public static methods get and set the FrameworkMain instance singleton. I call get from the WAR, and set from the jar. I could not add this to FrameworkMain, which is actually an interface in FrameworkBase jar (implemented by FrameworkMainImpl in the FrameworkBaseImpl jar).
Thanks.

Resources