How we can get under development dependency in maven - java

I encounter an issue that, I have 3 projects porject_1,porject_2 and porject_3.
porject_1 contains one abstract class for example ClassDef.java, and porject_2 and porject_3 are implementing ClassDef.java in there code some where.
If ClassDef.java has added some new API in porject_1(under development means not released yet ) which should be verified by porject_2 & porject_3.
But in maven porject_2 & porject_3 need porject_1 dependency to get new implementation and we can not add porject_1 development jar into class path of porject_2 & porject_3 project in maven hence I can't take latest change in both dependent project at same time. how could I resolve this issue?

Related

How to add com.fasterxml.jackson.core.exc.InputCoercionException as a dependency in gradle?

I am getting java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/PropertyNamingStrategies which is used in another project. I have included jackson jar in current gradle project as well. But while starting the project I am getting the above mentioned error. Seems like we need to add com.fasterxml.jackson.core.exc.InputCoercionException as an dependency but I am not able to understand where to add this as a dependency ? Can someone please help ?
java.lang.NoClassDefFoundError Either means - missing dependency with class com/fasterxml/jackson/databind/PropertyNamingStrategies or class was removed meaning jackson libs versions used in your project dependencies won't work together.
How to start solving problems like those.
1, Via IDE try to find missing class if is present. If is not present then try to find jar with missing class on internet and add as dependency. In case your IDE show class is present then problem may be with import scope. Scope management differ per used technology so provide detail which one you use or paste dependencies from build.kts . Make sure you use implementation in case you import this class in project and not runtimeOnly.
2, You found class then try to print project dependency tree command differ per used technology. For gradle ./gradlew dependencies or for submodule ./gradlew submoduleName:dependencies and look at versions of jackson in your project.
3, Check jackson lib with version listed via dependency tree contains missing class.
How to avoid problem like those with spring boot.
I would recoment to use BOM provided by spring boot project, versions in there should work together.
For gradle with kotlin DSL we import it like this
import org.springframework.boot.gradle.plugin.SpringBootPlugin
plugins {
id("org.springframework.boot") version "2.6.2"
}
dependencies {
val springBootPlatform = platform(SpringBootPlugin.BOM_COORDINATES)
annotationProcessor(springBootPlatform)
implementation(springBootPlatform)
//this version has to be searched for spring boot version
implementation(platform("org.springframework.cloud:spring-cloud-dependencies:2021.0.0"))
//put desired jackson dependencies
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
}

Jersey JSON application builds, fails

I have a Java web application that exposes several REST endpoints. They all work. They can be hit and return the expected data (plain text). I need them to return JSON instead. To do this, the application needs to:
Include the "jersey-media-moxy" jar
Include #XmlRootElement atop any POJO we want converted to JSON
I added the #XmlRootElement to the class. Our project builds with gradle. I added this line to the bottom of the dependencies section of our build.gradle file:
compile group: 'org.glassfish.jersey.media', name: 'jersey-media-moxy', version: '2.26'
It looks almost identical to the line above it:
compile group: 'org.glassfish.jersey.media', name: 'jersey-media-multipart', version: '2.22.2'
Except for the name and version, of course. It builds fine. I had to add the jar (jersey-media-moxy-2.26.jar) to our dependency hierarchy, but no big deal.
It runs fine, until the user logs in. A number of components on the main screen are missing, and it spews errors (the application always spews errors, but they are expected). The new errors are varied, but a repeated one is:
SEVERE: StandardWrapper.Throwable
java.lang.NoClassDefFoundError: jersey/repackaged/com/google/common/base/Predicate
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:177)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:369)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
...
The stack trace never includes any of our source code as the culprit. It's all org.glassfish.jersey and org.apache.catalina.core errors (we are using Tomcat as our server). Clearly, something is wrong.
I've tried more things to resolve it than I like to recall, but some include:
Adding the jersey-media-moxy in a different location of the 40 or so dependencies we have (no difference)
Explicitly adding all the jersey-media-moxy dependencies (even though it builds fine without them; no difference)
Removing the jersey-media-multipart dependency (build fails)
Scrapping the workspace and doing a fresh "get" from source control, and re-adding the jersey-media-moxy dependency (no difference)
Bringing the jersey-media-multipart up to the latest version (doesn't build)
Removed the jersey-media-moxy dependency to see if I really need it (who knows? Maybe jersey-media-multipart already contains it) and changed the object I'm returning to a very simple class (it just contains a string). (that fails, it really does need jersey-media-moxy)
I am the only Java developer here, and this is the first time I've used gradle or Jersey. There are other ways to produce JSON, I know (such as using gson), but we really want to have Jersey do it, since we're using the framework already.
We use Eclipse (Oxygen) as our IDE and Tomcat as our server.
One big question I have is why would a new jar break an existing one?
The second question is the big one, of course: what can I do to resolve this issue?
Your 2.26 and 2.22.2 discrepancy is probably the problem. Don't mix your Jersey module versions.
why would a new jar break an existing one?
Because it isn't just a single jar that you are adding. When using a dependency management system like with Maven or Gradle, you are dealing with dependencies not just jars, and the ones that you explicitly list can have their own dependencies that implicitly get pulled in. For instance if you were to just add jersey-media-moxy, it would pull in like 10+ extra jars.
The problem with this is that if you use incompatible version, both jersey-media-moxy and jersey-media-multipart pull in some of the same jars, put you can't have more than one version of a class. So only one of the classes from those two jars will be used. And as you know, software changes with version changes. So one class might be trying to use a class that exists in one version and not in another version. This is just one of the problems you can face if you don't manage your dependencies versions correctly.

How to pin latest version of a maven artifact while creating a project from archetype

I have an archetype that we use to create new projects. At the point of project creation (i.e. when someone executes mvn archetype:generate) I want to pin some of the dependencies to RELEASE version available at that time (I strongly oppose putting <version>RELEASE</version> in POM file).
Is there a way I can make archetype to resolve RELEASE version and pin that for some of the libraries.
Only way I solve this problem right now is by releasing new version of archetype every time some of the core libraries are released and then hard coding versions of those in the archetype-resources/pom.xml
I did see couple of similar questions but none of the solutions for those work for me.
As I already mentioned, that I want to pin the latest release version available at the time of creating project from archetype. Using `RELEASE means that I can not recreate binaries from same source code as I will end up fetching a different version of dependency.
Let me explain with concrete example.
I have an archetype with maven co-ordinate com.my-company:my-awesome-framework:1.0.
I have a library with maven co-ordinates com.my-company:core-lib:1.0.
Developer-1 runs command mvn archeype:generate my-awesome-framework. He fills in required details and creates project called service-foo. service -foo has dependency core-lib and since.
We add more features to core-lib and release version 2.0
Developer-1 build service-foo it still builds with core-lib version 1.0. (since he hasn't changed the version the project's POM file. Had I used <version>RELEASE<version> for 'core-lib, this timeservice-foowould have built with version2.0of thecore-lib`)
Devloper-2 runs mvn archetype:generate my-awesome-framework. He fills out required fields and creates a service called service-bar. Now this time since core-lib version 2.0. Note that I did not modify my-awesome-archetype to update version for core-lib inside archetype-resources\pom.xml
I hope this clarifies my use case
I solved this using archetype-post-generate.groovy, script. Maven archetype plugin executes that (if available) after the project has been created. There one can use Maven versions plugin to update to the latest releases.
Here is an example how you can update both versions in properties and in parent project (in Spring Boot in this case):
dir = new File(new File(request.outputDirectory), request.artifactId)
def run(String cmd) {
def process = cmd.execute(null, dir)
process.waitForProcessOutput((Appendable)System.out, System.err)
if (process.exitValue() != 0) {
throw new Exception("Command '$cmd' exited with code: ${process.exitValue()}")
}
}
run("echo 'Updating to latest Vaadin version...'")
run("mvn versions:update-properties")
run("echo 'Updating to latest Spring Boot version...'")
run("mvn versions:update-parent")
The downside is that Eclipse don't seem to execute that script, but in other major IDEs and command line this work just fine.
The groovy script form my Vaadin + Spring Boot archetype in GitHub.

Can I force the order of dependencies in my classpath with Gradle?

A project runs on Google App Engine. The project has dependency that uses a class that can't be invoked on App Engine due to security constraints (it's not on the whitelist). My (very hacky) solution was to just copy a modified version of that class into my project (matching the original Class's name and package) that doesn't need the restricted class. This works on both dev and live, I assume because my source appears in the classpath before my external dependencies.
To make it a bit cleaner, I decided to put my modified version of that class into it's own project that can be packaged up in a jar and published for anyone else to use should they face this problem.
Here's my build.gradle:
// my jar that has 'fixed' version of Class.
compile files('path/to/my-hack-0.0.1.jar')
// dependency that includes class that won't run on appengine
compile 'org.elasticsearch:elasticsearch:1.4.4'
On my local dev server, this works fine, the code finds my hacked version of the class first at runtime. On live, for some unknown reason, the version in the elasticsearch dependency is loaded first.
I know having two versions of the same class in the classpath isn't ideal but I was hoping I could reliably force my version to be at the start of the classpath. Any ideas? Alternatively, is there a better way to solve this problem?
Not really sure if this is what people visiting this question were looking for, but this was what my problem and a solution that I reached at.
Jar A: contains class XYZ
Jar B: also contains class XYZ
My Project needs Jar B on the classpath before Jar A to be able to get compiled.
Problem is Gradle sorts the dependencies based on alphabetical order post resolving them which meant Jar B will be coming after Jar A in the generated classpath leading to error while compiling.
Solution:
Declare a custom configuration and patch the compileClasspath. This is how the relevant portion of build.gradle might look like.
configurations {
priority
sourceSets.main.compileClasspath = configurations.priority + sourceSets.main.compileClasspath
}
dependencies {
priority 'org.blah:JarB:2.3'
compile 'org.blah:JarA:2.4'
...
}
It's the app engine classloader I should have been investigating, not gradle...
App Engine allows you to customise the class loader JAR ordering with a little bit of xml in your appengine-web.xml. In my case:
<class-loader-config>
<priority-specifier filename="my-hack-0.0.1.jar"/>
</class-loader-config>
This places my-hack-0.0.1.jar as the first JAR file to be searched for classes, barring those in the directory war/WEB-INF/classes/.
...Thanks to a nudge in the right direction from #Danilo Tommasina :)
UPDATE 2020:
I just hit the same problem again and came across my own question... This time, live appengine was loading a different version of org.json than was being loaded in dev. Very frustrating and no amount of fiddling the build script would fix it. For future searchers, if you're getting this:
java.lang.NoSuchMethodError: org.json.JSONObject.keySet()Ljava/util/Set;
It's because it's loading an old org.json dependency from god-knows-where. I fixed it by adding this to my appengine-web.xml:
<class-loader-config>
<priority-specifier filename="json-20180130.jar"/>
</class-loader-config>
You'll also need a matching dependency in build.gradle if you don't already have one:
compile 'org.json:json:20180130'
According to gradle dependencies documentation, the order of dependencies defines the order in the classpath. So, we can simply put the libraries in the correct order in "dependencies".
But beware! here are two rules with higher priorities:
For a dynamic version, a 'higher' static version is preferred over a 'lower' version.
Modules declared by a module descriptor file (Ivy or POM file) are preferred over modules that have an artifact file only.

NoSuchMethodError after cleaning the project

I'm currently getting this error:
java.lang.NoSuchMethodError: org.json.JSONObject.keySet()Ljava/util/Set;
at ee.ut.cs.Parser.accessLint(Parser.java:39)
I have tried cleaning the project to no awail.
I suspect I have an error in the src/plugin/parse-htmlraw/build.xml while creating the jar file but I'm not certain. I understand that this error is because the function does not exist at runtime, but the object is created which means that the class is there, just not that function. I decompiled the .class file in created jar and it has the necessary functions.
Code is available at https://github.com/jaansusi/WCAGgrader
Q: What is wrong with the build that produces this error?
The problem is that even if I put the necessary class files in the jar I create, they are not linked correctly and the class that's called in the jar can't locate functions inside the other classes. The class object JSONObject is created but the functions inside the JSONObject class can't be found.
If you do not find the problematic version, there is a possibility you get it (especially if you are using Spring) from the following dependency -
<artifactId>android-json</artifactId>
<groupId>com.vaadin.external.google</groupId>
excluding it worked for me,
An easy way of analyzing dependencies is the maven-helper plugin in Intellij, see here
Check for the version you have used.
There might be a case where 2 different versions are being used which in turn causes this error.
To their own maven local repository com\Google\code\gson\gson, see if there are two or more version about json, will have to do is to delete the old, and remember to look at any other place in the project is introduced into the old version of the dependence, if any, change the old version of the dependence to the new version is perfectly solved this problem

Categories

Resources