Run two versions of elasticsearch in java application using maven - java

I have a legacy monolith application, which uses elasticsearch 1.X and now we need to run elasticsearch 7.X in the same application, so that same application index and query data in both version of elasticsearch.
In my project, there are multiple modules and they all have their own POM and parent POM, and my new module which uses elasticsearch 7.X depends on some module which uses 1.X.
Although I have excluded 1.X specific dependency in module which uses 7.X, Still it gives me below Error:
[76B7CCD2] java.lang.NoSuchFieldError: LATEST at
org.elasticsearch.Version.(Version.java:49) at
org.elasticsearch.common.io.stream.StreamInput.(StreamInput.java:114)
After doing a lot of research and using this and this link, As explained I excluded the elastic 1.x dependency but still looks like as my other sub-module still has ES 1.X and which is required as well, hence overall classpath of my application has both versions of org.elasticsearch.Version java class from the same package org.elasticsearch, which I feel is the root cause.
Now, How can I include the same class from the same package from two different versions of a same library.

You can't. You can only have one class with a given full qualified name (package + name).
You can try to shade one of the packages (i.e. rename it) with the Maven shade plugin (never tried that, actually), which might work.
Usually, you need to change code and fiddle around until you find a version of elasticsearch that works with all dependencies.

Related

Managing common dependencies across plugins

I have implemented a springboot application that can be extended by loading plugins into it. The plugins are created by extending from a common interface specified in my library (LibA) and loaded into the springboot application using Java SPI. Because of this, LibA is a dependency to the springboot application.
There are some common libraries (LibB, LibC) that are used by the plugins which are not part of the springboot application.
The current implementation requires each plugin to be a fat jar containing LibA, LibB, LibC and because of this the versions of the libs need to be the same otherwise there will be issues (such as method not found) while loading these plugins.
I would like to have these common libraries as part of the springboot application and have the plugins refer to the versions in the application. Doing this could result in smaller jars and also ensure the consistency of the version of the libraries used by the plugins.
I could specify LibA, LibB and LibC as dependencies of the springboot application and have the plugins remove them from it's jar and things might work but this would still require the versions to be specified in the plugin's build.gradle.
What I want to know is how to have something similar to the way springboot specifies and provides it's dependencies. Other ways to manage this is also appreciated. I'm using gradle as the build tool.
Current
App (LibA), plugins (LibA, LibB, LibC)
What i need
App (LibA, LibB, LibC), plugins (just refer to the versions in app)
I'm unsure if this is the correct channel to post this question, let me know if it's not suitable.

How to build a library around spring-boot that doesn't enforce a certain spring-boot version?

I am trying to build a library https://github.com/mhewedy/spring-data-jpa-mongodb-expressions on top of spring boot and spring Data JPA.
What I want to achieve and hence the library doesn't use explicitly implementation feature of spring boot or spring data JPA, I need to make this a library to take the version from the including project.
Currently, the version of spring boot is defined in the pom.xml
So, I think once I uploaded the jar to the maven repository, and whenever anybody depends on this jar, there might be a conflict in the spring dependencies (that comes from his project and what comes from this jar)
So my question is If I make the dependencies in pom.xml as Optional, do this will solve the problem? if not what other alternative solutions I can do?
EDIT:
Here's a list of types from spring I use in the library:
org.springframework.data.jpa.repository.JpaRepository;
org.springframework.data.repository.NoRepositoryBean;
org.springframework.data.domain.Page;
org.springframework.data.domain.Pageable;
org.springframework.data.domain.Sort;
org.springframework.data.jpa.domain.Specification;
org.springframework.data.jpa.repository.support.JpaEntityInformation;
org.springframework.data.jpa.repository.support.SimpleJpaRepository;
For building your library, you need to use a given version of the dependencies. You need to choose one, otherwise the compiler cannot create a classpath and compile your code.
Somebody who uses your library might use another version of the dependencies. Their versions will (usually) override your versions because they win in the Maven dependency mediation. So your library will actually run with the versions that the library user specifies (if the library user does not use your dependencies, then your versions are still there).
So, the question that remains is: Will your code work with a newer/different version of the dependencies?
This cannot be said in general because it depends on the way the maintainer of the dependencies works.

Need Different Versioned Dependencies In the Same Project

I have a project that has two needed dependencies for it. These dependencies have in turn apache cxf dependencies. Dependency A uses apache cxf versions 2.4.0 where dependency B uses apache cxf versions 3.1.0.
Because classes were changed between the versions, using one or the other results in ClassNotFoundException's.
A little description of what they are, Dependency A is the client jar for some old SOAP webservices. This includes the autogenerated files from wsdl2java. Dependency B is the client jar for a new REST webservice.
The main project uses Maven to handle dependencies, is a war, and is on tomcat 7.
Any thoughts for what I could do to try and get this to work correctly? I have already tried making the REST client a jar-with-dependencies and bringing it in through Tomcat's common classloader with no luck.
EDIT
After reviewing the dependencies I am bringing in, I can't simply update the dependencies because I do not have control of some of the dependencies being brought in. I would need to alter what those jars are doing and that will not work.
Its never a good idea to use two version of same dependency as it can create discrepancies in your project.
Ideally you should latest version and then make the old code compatible with latest version

Resolving transitive dependency conflicts in Java

I am trying to build a Dropwizard (Jersey) REST endpoint that communicates with HBase. Although these are my only two top-level dependencies, both of these dependencies come loaded with many transitive dependencies that conflict. A simple example of such a conflict is Google's Guava:
The HBase client specifies version 11
Dropwizard specifies 18
Dropwizard will not work with version 11 and HBase will not work with version 18.
I have examined the Maven shade plugin documentation, but it does not seem to let you relocate classes found in dependency jars. So I don't know how to resolve this issue short of separating these two components into separate JVMs.
This is a dirty solution. But you could...
Create a project / module where you define a set of service interfaces that your dropwizard app will use to talk to HBase.
Create another module / project that implements these interfaces and uses the HBase classes. Shade this project.
In your Dropwizard project include only the interface jar but create a task to copy the shaded artifact into your resources.
Create a JARClassLoader for your shaded HBase client artifact. You may have to make a special subclass that does not delegate to the parent as by default the classloader will ask the parent to resolve linkages and may pull the newer version of guava from outer classloader.
Ask for an instance of the service contract from the Jar loader...
Businessing api = Class.forName("com.awesome.Businessing", true, jarLoader).newInstance();
Try to specify concrete versions for those dependencies in <dependencyManagement/> section of you pom.xml.

IBM SBT SDK 1.1.0 (Java) and Apache xerces

I am adding IC integration with IBM SBT SDK (Java) into an existing project which still uses xerces 2.4.0 (as of March 2009).
Using IBM SBT SDK 1.0.x did not cause any problems here, but the XML serialization implementation of 1.1.0 completely relies on org.w3c.xml.ls.DOMImplementationLS and such stuff which was introduced after moving xerces to "xercesImpl" about 2004.
However the project contains much code working with XML based on xerces and xml-apis, and it looks dangerous to move too fast to "more current" versions of these libraries. Thus I want to move "no further than absolutely required".
Thanks to maven no one can directly see which version of any artifact is loaded if it is not directly referenced in the pom.xml. Thus my question:
Which version of xercesImpl is "really" required by IBM SBT SDK 1.1.0? 2.4.0 is not sufficient, as some methods used in the SBT SDK are not yet implemented there...
xerces version in the dependency would be 2.9.0; looking at the DOMUtil.java#loadDriver() class however there are workarounds to avoid the SBTK to use xerces altogether:
if your container allows to control the classpath tree, shadowing the xerces library from the toolkit will have it default to some other driver. In alternative you can provide your own XercesDriver class compatible with old xerces versions and leverage the classloader to have it loaded in place of ours.
if you are in a osgi container you can also make sure the host application manifest declares a dependency to a version <=2.4.0 and load both xerces versions letting the container fix the dependencies for you
anyway, to answer the question, using:
mvn dependency:list
I get version 2.9.0 for xerces:
The following files have been resolved:
com.ibm.sbt:com.ibm.commons:eclipse-plugin:9.0.0:provided
p2.eclipse-plugin:javax.servlet:jar:3.0.0.v201112011016:system
p2.eclipse-plugin:javax.xml:jar:1.3.4.v201005080400:system
p2.eclipse-plugin:org.apache.xalan:jar:2.7.1.v201005080400:system
p2.eclipse-plugin:org.apache.xerces:jar:2.9.0.v201101211617:system
p2.eclipse-plugin:org.apache.xml.resolver:jar:1.2.0.v201005080400:system
p2.eclipse-plugin:org.apache.xml.serializer:jar:2.7.1.v201005080400:system
p2.eclipse-plugin:org.eclipse.core.contenttype:jar:3.4.200.v20120523-2004:system
p2.eclipse-plugin:org.eclipse.core.jobs:jar:3.5.300.v20120912-155018:system
p2.eclipse-plugin:org.eclipse.core.runtime:jar:3.8.0.v20120912-155025:system
p2.eclipse-plugin:org.eclipse.equinox.app:jar:1.3.100.v20120522-1841:system
p2.eclipse-plugin:org.eclipse.equinox.common:jar:3.6.100.v20120522-1841:system
p2.eclipse-plugin:org.eclipse.equinox.preferences:jar:3.5.1.v20121031-182809:system
p2.eclipse-plugin:org.eclipse.equinox.registry:jar:3.5.200.v20120522-1841:system
p2.eclipse-plugin:org.eclipse.osgi:jar:3.8.2.v20130124-134944:system

Categories

Resources