Custom dependencies are not identified in Spring-Boot - java

I have two spring-boot project
greeter-library
greeter-spring-boot-autoconfigure
I have created jar file for greeter-library and installed that in my local m2(maven) repository.
Now I am using that jar as a maven dependency in greeter-spring-boot-autoconfigure.But it is stating
Class not found on Greeter.java.
pom.xml for greeter-library
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<artifactId>greeter-library</artifactId>
<groupId>com.xyz.greeter</groupId>
<version>0.0.1-SNAPSHOT</version>
<name>greeter-library</name>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Now pom.xml for greeter-spring-boot-autoconfigure is as follows
<artifactId>greeter-spring-boot-autoconfigure</artifactId>
<name>greeter-spring-boot-autoconfigure</name>
<groupId>com.xyz</groupId>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<artifactId>greeter-library</artifactId>
<groupId>com.xyz.greeter</groupId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
But during maven build time for greeter-spring-boot-autoconfigure, it is stating that Greeter.java not found which is part of greeter-library project.
Can anyone has any solution to this?

Since you've added spring-boot-maven-plugin in "greeter-library" module, it will be packaged as a spring boot application. Open it with WinRar/WinZip and you'll see. This is a little bit confusing, but in general spring boot application, although is packed as a JAR is not actually a jar in the sense that JVM can't load it, can't find its classes automatically, etc. For example, it has its dependencies in BOOT-INF/lib folder - this is not the way regular jars work, in fact, spring boot has a bootstrapping code that uses custom class loaders to read the classes from such a structure.
As a consequence of all this, Maven and IDE won't be able to recognize the classes from the greeter-library hence the error. Bootom line, you can't really declare a dependency on a spring boot application from your greater-spring-boot-autoconfigure module.
Now as a solution - why do you need a greeter-library to be a spring boot artifact? Maybe if you just remove the spring-boot-maven-plugin and turn it to the regular jar (with regular dependencies on spring boot infrastructure perhaps) it will work?
If this doesn't help, feel free to share more details in the question to get a more precise solution to the problem...

Some ideas to explore
the first jar "greeter-library" doesnt need to be packed for spring-boot, it can be a normal jar file.
Create a spring.factories file under src/resources/META-INF path. Expose the java classes from this JAR that can be used by "greeter-spring-boot-autoconfigure"

Related

java: cannot find symbol symbol: class CassandraClusterFactoryBean

I m developing spring cloud project based microservice.(packaging maven)I m using cassandra on docker image in project. I m taking error in CassandraConfiguration. I imported "import org.springframework.data.cassandra.config.CassandraClusterFactoryBean;" in CassandraConfiguration ,but I took error. Error Message in intellij idea. I tried to run this project on eclipse. I got an error again. Thank you!
java: cannot find symbol
symbol: class Cassandra Cluster Factory Bean
location: class com.accountservice.springcloudmicroserviceaccount.Configuration.CassandraConfiguration
import org.springframework.data.cassandra.config.CassandraClusterFactoryBean;
and public CassandraClusterFactoryBean cluster(){
CassandraClusterFactoryBean cluster=super.cluster();
cluster.setUsername(username);
cluster.setPassword(password);
return cluster;
}
I tried to do something pom.xml. I searched solve on this website, but I got an error again.
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.accountservice</groupId>
<artifactId>springcloudmicroserviceaccount</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springcloudmicroserviceaccount</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-cassandra</artifactId>
</dependency>
<dependency>
<groupId>com.codahale.metrics</groupId>
<artifactId>metrics-core</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>19</source>
<target>19</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
CassandraClusterFactoryBean was removed in 2019 with the migration to Cassandra driver 4. All details can be found in the original pull request on GitHub: https://github.com/spring-projects/spring-data-cassandra/pull/167
Breaking changes:
Removal of types (without replacement):
[…]
CassandraCqlClusterFactoryBean
[…]
Configuration summary
Driver 4 merges Cluster and Session objects into a single CqlSession object,
therefore all Cluster-related API was removed. The Configuration was revised
in large parts by removing most configuration items that were moved into
DriverConfigLoader that is mostly file-based. This means that SocketOptions,
AddressTranslator and many more options are configured now through other
means.
Further information:
https://docs.datastax.com/en/developer/java-driver/4.3/
https://docs.datastax.com/en/developer/java-driver/4.3/upgrade_guide/
[emphasis mine]
More information quoted from the upgrade guide:
Cluster does not exist anymore; the session is now the main component, initialized in a single step:
CqlSession session = CqlSession.builder().build();
session.execute("...");

NoSuchMethodError because wrong class is found

I have a Sprint Boot application and at deployment time I'm getting a NoSuchMethodError. I'm deploying to WebSphere 8.5.5.13. I'm pretty sure it's because the wrong class or version of the class is being found. It seems like the Spring code is looking for it's own class but is finding a class from the IBM jar file and the class it loads doesn't have an 'init()' method on it.
Please let me know if any further information will help determine a fix.
Here's my pom.xml file:
<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.companygoeshere</groupId>
<artifactId>eacmanager</artifactId>
<version>0.0.2-SNAPSHOT</version>
<packaging>war</packaging>
<name>EACManager</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<type>pom</type>
<version>5.0.7.RELEASE</version>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.extensions</groupId>
<artifactId>spring-security-saml2-core</artifactId>
<version>1.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-base</artifactId>
</dependency>
<dependency>
<groupId>ca.juliusdavies</groupId>
<artifactId>not-yet-commons-ssl</artifactId>
<version>0.3.11</version>
</dependency>
<dependency>
<groupId>org.opensaml</groupId>
<artifactId>opensaml</artifactId>
<version>2.6.4</version>
</dependency>
<dependency>
<groupId>com.microsoft.ews-java-api</groupId>
<artifactId>ews-java-api</artifactId>
<version>2.0</version>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Here's the error message:
> com.ibm.ws.exception.RuntimeWarning:
> com.ibm.ws.exception.RuntimeWarning:
> com.ibm.ws.webcontainer.exception.WebAppNotLoadedException: Failed to
> load webapp: Failed to load webapp: Error creating bean with name
> &#39;defaultValidator&#39; defined in class path
> resource
> [org/springframework/boot/autoconfigure/validation/ValidationAutoConfiguration.class]:
> Invocation of init method failed&#59; nested exception is
> java.lang.NoSuchMethodError:
> javax/validation/Configuration.getDefaultParameterNameProvider&#40;&#41;Ljavax/validation/ParameterNameProvider&#59;
> &#40;loaded from file:/C:/Program Files
> &#40;x86&#41;**/IBM/WebSphere/AppServer/plugins/javax.j2ee.validation.jar** by
> org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader#3fb9923&#41;
> called from class
> org.springframework.validation.beanvalidation.LocalValidatorFactoryBean
> &#40;loaded from
> file:/C:/Program&#37;20Files&#37;20&#40;x86&#41;/IBM/WebSphere/AppServer/profiles/AppSrv01/installedApps/TheGarbers3Node01Cell/eacmanagerEAR.ear/eacmanager.war/WEB-INF/lib/spring-context-5.0.7.RELEASE.jar
> by
> com.ibm.ws.classloader.CompoundClassLoader#79b97694[war:eacmanagerEAR/eacmanager.war]
To do this, you need to change the classloader of your application so the correct dependency is pulled in.
To do that via the UI, go to Applications -> WebSphere enterprise applications -> Your Application -> Class loading and update detection and change the Class loader order to be Classes loaded with local class loader first (parent last). This "causes the class loader to attempt to load classes from its local class path before delegating the class loading to its parent.".
If you are deploying an EAR and want this change to propagate to inner applications, you can either change WAR class loader policy to Single class loader for application or change the class loader of the individual war (in the EAR click Manage Modules -> Your Module then change Class loader order).
As long as you provide a version of dependency in question, you should get passed the above issue.
The following wasadmin.sh script will apply the above settings (replace app_name with the name of your application): (credit)
dep = AdminConfig.getid('/Deployment:app_name/');
depObject = AdminConfig.showAttribute(dep, 'deployedObject');
AdminConfig.modify(depObject, [['warClassLoaderPolicy', 'SINGLE']]);
classldr = AdminConfig.showAttribute(depObject, 'classloader');
AdminConfig.modify(classldr, [['mode', 'PARENT_LAST']]);
Try changing the version of springboot in your pom.xml. It may work by referring different version of lib files
2.0.3.RELEASE --> 1.5-.59 etc
Smells like a you have multiple versions of the same dependency on your classpath. You compile with one but you are running the other.
Run mvn dependency:tree and you can see everything you're bringing in.
Often times transitive dependencies can cause the problems you're experiencing-- i.e, your webapp depends on both library Foo-v1 and Bar-v1. However, Foo-v1 itself depends on Bar-v2.
Once you find the duplicate library, try bumping each to be the same or latest version. Another approach is to try using maven's <exclusion></exclusion> so you only have one version of that library in your jar.
See this: https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html

How can I use my own parent.pom instead of the "spring-boot-starter-parent"?

I am new to Spring, Spring boot, and Spring boot starter.
For my different apps I use an own parent.pom for what the have in common. The parent.pom contains the version numbers as properties and dependencies that use the properties as version numbers.
When using my parent.pom maven states that I have to use the "spring-boot-starter-parent".
How can I use my own parent.pom instead of the "spring-boot-starter-parent"?
Meanwhile I changed the pom to this:
<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.websystique.springboot</groupId>
<artifactId>SpringBootRestApiExample</artifactId>
<version>1.0.0</version>
<name>SpringBootRestApiExample</name>
<parent>
<groupId>my</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Add typical dependencies for a web application -->
<!-- Adds Tomcat and Spring MVC, along others -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.0.1.RELEASE</version>
</plugin>
</plugins>
</build>
</project>
But now I get this warning:
dependencies.dependency.scope' for org.springframework.boot:spring-boot-starter-parent:pom must be one of [provided, compile, runtime, test, system] but is 'import'. # line 27, column 1
You don't have to use spring-boot-starter-parent, it's just that it has an extensive dependencyManagement section that ensures all the Spring Boot dependencies you use in child projects have mutually compatible versions.
I typically declare spring-boot-starter-parent as the parent POM of my parent POM. This way, you get the best of both options.
It is also possible to import the spring-boot-starter-parent pom. So you can use your own pom as parent and you can use the dependency management from the spring boot pom.
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
...

Spring boot and elastic search unsupported version minimal compatible version

This is my pom.xml
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
it.test
searchTest
0.0.1-SNAPSHOT
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.M5</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Runtime, for Embedded Elasticsearch,
comment this if connect to external elastic search server-->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Package as an executable jar/war -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
When I start my project I have returned this stack trace:
[2017-12-15T13:36:15,670][WARN ][o.e.t.n.Netty4Transport ] [node1] exception caught on transport layer [org.elasticsearch.transport.netty4.NettyTcpChannel#7c08d374], closing connection
java.lang.IllegalStateException: Received message from unsupported version: [5.5.3] minimal compatible version is: [5.6.0]
at org.elasticsearch.transport.TcpTransport.ensureVersionCompatibility(TcpTransport.java:1428) ~[elasticsearch-6.1.0.jar:6.1.0]
at org.elasticsearch.transport.TcpTransport.messageReceived(TcpTransport.java:1375) ~[elasticsearch-6.1.0.jar:6.1.0]
at org.elasticsearch.transport.netty4.Netty4MessageChannelHandler.channelRead(Netty4MessageChannelHandler.java:64) ~[transport-netty4-6.1.0.jar:6.1.0]
What I have to change in my pom to solve this incompatibility?
Thanks
Change the transport version to be the same as your elasticsearch instance
What is the version of your ElasticSearch, Maybe you can try to add this property in your pom like this.
<properties>
<elasticsearch.version>6.1.0</elasticsearch.version>
</properties>
I always find the Spring data elasticsearch matrix table useful for figuring out what compatible version to use.
To change version of ES from to a compatible version use the Spring Boot dedicated module to specify dependency versions. Add elasticsearch.version into your pom properties
<properties>
...
<elasticsearch.version>1.7.2</elasticsearch.version>
...
</properties>
i too was getting similar error but got resolved, before which i like to highlight my spring boot starter parent version which is 1.5.9.RELEASE, secondly i was using spring-boot-starter-data-elasticsearch artifact alone for spring boot elastic search and other artifacts can be removed, finally the phenomenal issue which you are receiving with the elastic search application which you have installed, try to download this version https://www.elastic.co/downloads/past-releases/elasticsearch-2-4-0 and try again....

Is it possible to use jersey and java websockets (ServerEndpoint) in the same project

While I was developing a rest api application with jersey, I came to a point that I needed to implement a websocket endpoint for a particular piece of business logic.
I am using maven in my project so I added javax:javaee-api dependency, but when I entered the server endpoint annotation (#ServerEndpoint) it couldn't be resolved. I tried to import it manualy (import javax.websocket.*) and I saw that in the javax package there was no websocket sub-package, only ws,xml,swing,validation,etc. I tried to add javax.websocket:javax.websocket-api as a dependency instead of whole javaee-api, but I got the same result.
I searched on the web and on stackoverflow I found this question (Integrating JaxRS REST service with WebSockets) that is similar to mine but still has no answer about websockets. The guy that asked this question, solved his problem using jersey's SSE (Server-Sent Events).
My question is (as the title says): Is it possible to use jersey and java websockets in the same project, or i need to create a separate project and use reference or some kind of custom made broker class.
On request of Paul Wasilewski I append my pom.xml below. As you can see I added javaee-api dependency in the pom, but is not downloaded in the external libs (I use IntelliJ). I created new (clean) maven project and added the same dependency. In this new project, the javaee-api artifact was downloaded perfectly and I can access javax.websocket namespace.
I ask this question because I think that there is some dependency conflict in jersey with the javaee-api artifact.
<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>edu.finki.misw.busline</groupId>
<artifactId>busline</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>busline</name>
<build>
<finalName>busline</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<inherited>true</inherited>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax/javaee-api -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<!-- artifactId>jersey-container-servlet</artifactId -->
</dependency>
<!-- uncomment this to get JSON support
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
-->
</dependencies>
<properties>
<jersey.version>2.23.2</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
Sure you can use websocket and rs services in the same project.
To add websocket support to your maven project add the following dependency to your pom.
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>

Categories