Is it possible in main app to use dependancies from added dependancies? - java

The problem I have is that I have a Library which I want to use in the Main App. In the Library I have added external libraries, and the question is, is it possible to use directly code of this external libraries in Main App despite of that these libraries are not added directly to Main App but to my Library?
I've added my Library to pom.xml in Main App and I can use the code that is written there, but I have problem using Library classes that extends external library classes, because Spring throws ClassNotFoundException
I've tried #ComponentScan in Main App and as argument I passed the main package of Library (com.project.common.starter), but it helped only with Components of the Library, but no external ones
---EDIT:
my Library 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
<relativePath/>
</parent>
<groupId>com.project.starter</groupId>
<artifactId>project-commons-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>project-commons-starter</name>
<description>project-commons-starter</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.external.library</groupId>
<artifactId>external-starter</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
</project>
my Main App 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
<relativePath/>
</parent>
<groupId>com.project</groupId>
<artifactId>project-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>main-app-name</name>
<description>main-app-desc</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
...
<dependency>
<groupId>com.project.starter</groupId>
<artifactId>project-commons-starter</artifactId>
<version>0.0.1</version>
</dependency>
</dependencies>
...
</project>
Class in Library that probably causes problem:
package com.project.starter.service;
import com.external.ExternalLibraryProcessor;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
#Component
public class LibraryProcessor implements ExternalLibraryProcessor {
#Override
public void process() {
String context = MDC.get(ContextUtils.REQUEST_CONTEXT)
doSmth...
}
}
my MainPortalApplication :
package com.project
#SpringBootApplication
#ComponentScan(basePackages = {"com.project","com.project.starter"})
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
ContextUtils.class:
public class ContextUtils {
private ContextUtils() {
}
public static final String REQUEST_CONTEXT = "requestContext";
}
When I run application I get:
Exception encountered during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.BeanDefinitionStoreException:
Failed to read candidate component class: URL [jar:file:/home/***/.m2/repository/com/project/project-commons-starter/0.0.1/project-commons-starter-0.0.1.jar!/com/project/starter/commons/ContextUtils.class];
nested exception is
org.springframework.beans.factory.CannotLoadBeanClassException: Error loading class [com.project.starter.service.LibraryProcessor] for bean with name 'libraryProcessor' defined in URL [jar:file:/home/***/.m2/repository/com/project/project-commons-starter/0.0.1/project-commons-starter-0.0.1.jar!/com/project/starter/service/LibraryProcessor.class]: problem with class file or dependent class;
nested exception is java.lang.NoClassDefFoundError: com/external/library/ExternalLibraryProcessor

The issue in my case was that I was using wrong maven command to compile my Library:
mvn install:install-file [...]
When using above .pom file has no dependencies which where included in Library.
When changed to mvn install it started working well - .pom file started to look like it should and Main App recognized transient dependencies.

Related

running multi module Java program built through Maven gets "Unexpected token" error

Trying to learn Maven using Peggy Fisher's "Multi Module Build Automation with Maven".
main module app has dependent modules createFile, madlib.
trying to run the java program, I am getting
java -cp "C:\Users\user\.m2\repository\com\lynda\app\1.0\app-1.0.jar";"C:\Users\user\Documents\Learn\Maven\Ex_Files_MMB_Maven\Exercise Files\Ch01\01_06\sample-multi-app\createFile\target\createFile-1.0.jar";"C:\Users\user\Documents\Learn\Maven\Ex_Files_MMB_Maven\Exercise Files\Ch01\01_06\sample-multi-app\madLib\target\madLib-1.0.jar" com.lynda.App
At line:1 char:337
+ ... 01\01_06\sample-multi-app\madLib\target\madLib-1.0.jar" com.lynda.App
+ ~~~~~~~~~~~~~
Unexpected token 'com.lynda.App' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnexpectedToken
parent 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>
<!-- parent coordinates -->
<parent>
<groupId>com.lynda</groupId>
<artifactId>multi-app</artifactId>
<version>1.0</version>
</parent>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<!-- project coordinates -->
<groupId>com.lynda</groupId>
<artifactId>app</artifactId>
<version>1.0</version>
<!-- project dependencies -->
<dependencies>
<dependency>
<groupId>com.lynda</groupId>
<artifactId>createFile</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.lynda</groupId>
<artifactId>madLib</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
App.java
package com.lynda;
import com.lynda.createfile.CreateFile;
import com.lynda.madlib.MadLib;
import java.io.FileNotFoundException;
public class App {
public static void main(String[] args) throws FileNotFoundException {
CreateFile.getWords();
//make sure you update the absolute file location with your project information
MadLib.createMadLib("C:\\Users\\user\\Documents\\Learn\\Maven\\Ex_Files_MMB_Maven\\Exercise Files\\Ch01\\01_06\\sample-multi-app\\words.txt");
}
}

How to use a Java class from an application in another application?

I have a class in an application (it is a Spring Boot project), for example:
package com.exemple.spring.springboot.model;
public class Employee {
...
}
And in the pom.xml I have this:
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.exemple.spring</groupId>
<artifactId>spring-boot</artifactId>
<version>0.0.1-SNAPSHOT</version>
...
Now I want to use this class Employee in another application like this:
package com.exe.spring.controller;
import org.springframework.stereotype.Controller;
import com.exemple.spring.springboot.model.Employee;
#Controller
public class EmployeeController {
public Employee getAnEmployee() {
...
}
}
I've build the JAR with mvn clean install for the first app and I've added it in the pom.xml of the second app like this:
<?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.exe.spring</groupId>
<artifactId>rest-client</artifactId>
<version>1.0-SNAPSHOT</version>
<name>rest-client</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.exemple.spring</groupId>
<artifactId>spring-boot</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
And the problem is that I cannot import the Employee class in the EmployeeController class. I've imported it manually like this import com.exemple.spring.springboot.model.Employee;, but Intellij show me an error: Cannot resolve symbol 'springboot'. I see that the dependency is presented in the local repository. It is very weird because Eclipse doens't see anything to import for Employee, and Intellij see the class but when I try to click on "Import class" it doesn't import anything. What can I do to import it correctly? Thank you!
You can not directly add it as dependency, it has to be present in one of certral/ local / remote repository.
You need to add the jar to repo, e.g. local repoository,
mvn install:install-file -DlocalRepositoryPath=repo -DcreateChecksum=true -Dpackaging=jar -Dfile=[your-jar] -DgroupId=[...] -DartifactId=[...] -Dversion=[...]
And then add repository as,
<repository>
<id>repo</id>
<url>file://${project.basedir}/repo</url>
</repository>
Check other optios here
Check follow:
You've used mvn clean install to build and install the first JAR.
You have your JAR in the classpath of the second app. You can see all
of them in "External libraries" in idea. If not, reimport maven project or use auto-import option
Also you can use different maven project structure e.g :
Common parent
|
|-------> first jar
|
|-------> second jar (with first one as a dependency)
I think it should work better for you.

Spring method present in code, but not present in JAR

I would like to invoke that method:
https://github.com/spring-projects/spring-boot/blob/2.0.x/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ErrorProperties.java#L73
But it's not available. It's not even present in decompiled code. But it should be, since JavaDoc says it's available from 1.3.0 version and it's public. My version is 2.0.0, I also checked 1.5.4. The link I gave is for 2.0.x and in GitHub it's still there. But in code it's not available, why?
POM:
<?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>test</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
</dependencies>
</project>
Code:
import org.springframework.boot.autoconfigure.web.ErrorProperties;
public class Test {
ErrorProperties errorProperties = new ErrorProperties();
public Test() {
//Cannot resolve method getWhitelabel()
errorProperties.getWhitelabel();
}
}
That method is not in 2.0.0, nor in 2.0.3, but it is in 2.0.4 (the current latest version).
Change your pom.xml to:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.0.4.RELEASE</version>
</dependency>
</dependencies>
And it will compile.

Spring Boot: Application is displaying 404 error

I am trying to run Spring Boot REST API application, but I am getting a 404 error.
package com.spring.boot.entry;
#SpringBootApplication
#ComponentScan(basePackageClasses = HelloController.class)
public class CourseApiApp {
public static void main(String[] args) {
SpringApplication.run(CourseApiApp.class, args);
}
}
package com.spring.boot.entry.hello;
#RestController
public class HelloController {
#RequestMapping("/hello")
public String sayHello() {
return "Hi First Spring boot application ";
}
}
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>
<groupId>io.spring.boot.quickstart</groupId>
<artifactId>course-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Spring Boot API</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
</project>
I also tried #ComponentScan(basePackageClasses = HelloController.class),
but no luck. Could you please help to resolve this issue?
If I hit http://localhost:8080/hello url then I am getting 404.
I executed your code on my system and unless you've messed up with the directory structure it is working as expected. Cross check that once.
CourseApiApp.java
HelloController.java
Output

Spring application doesn't work after building in jar

I have a simple Spring application:
Main class:
#SpringBootApplication
#EnableScheduling
public class SchedulerApplication {
public static void main(String[] args) {
SpringApplication.run(SchedulerApplication.class, args);
}
}
And class for scheduled job
#Component
public class Executor {
private static final Logger log = LoggerFactory.getLogger(Executor.class);
private Integer jobCounter = 1;
#Scheduled(fixedDelay = 1000)
public void run() {
log.info("Start task (" + jobCounter + ")");
log.info("Stop task");
jobCounter ++;
}
}
This is 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>ru.alexeyzhulin</groupId>
<artifactId>scheduler</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>scheduler</name>
<description>Task scheduler</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.4.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</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
That is my project structure
It works fine under the IDE (IntelliJ IDEA), but when I compiled this code to jar file and run:
java -jar scheduler.jar
I got a long stack of errors like this
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [ru.alexeyzhulin.SchedulerApplication]; nested exception is java.lang.IllegalArgumentException: No auto configuration classes found in META-INF/spring.f actories. If you are using a custom packaging, make sure that file is correct.
What have I missed?
Add the following element under your sprig boot maven plugin in pom.
<configuration>
<fork>true</fork>
<mainClass>Your-main-config-class</mainClass>
</configuration>
It seems that your SpringBootApplication class located in a wrong place.
It should be properly located. Usually it is in a root of your artifact package.
For example:
ru.alexeyzhulin.scheduler
ru.alexeyzhulin.scheduler.SchedulerApplication
ru.alexeyzhulin.scheduler.Executor
or
ru.alexeyzhulin.scheduler
ru.alexeyzhulin.scheduler.SchedulerApplication
ru.alexeyzhulin.scheduler.components
ru.alexeyzhulin.scheduler.components.Executor
And look at it:
Failed to process import candidates for configuration class

Categories

Resources