How to handle dependency in maven project? - maven

I have a project A which has B as parent in it's pom.xml and I am getting all the dependencies. Now I need a class P which has been defined in project X and I can use that only if I include Y as a parent (so I think it is case of transitive dependency, though I am not sure if this is a correct understanding).
Now as my project A already has a parent defined so I cannot define Y in the same pom.xml and hence I am not able to get the class P in project A. I tried adding X as normal dependency but I am getting cannot resolve dependency while building project.
How can I handle this ?

If you want to use a class of X, you need to declare X as dependency, not as parent.

Related

Share configuration dependencies using extendsFrom with control over order

Received this warning in my gradle build this morning, and trying to figure out how to solve it
Adding a Configuration as a dependency is a confusing behavior
which isn't recommended. This behaviour has been deprecated
and is scheduled to be removed in Gradle 8.0. If you're
interested in inheriting the dependencies from the
Configuration you are adding, you should use extendsFrom
Following up on this answer... I was using the configuration as a dependency approach so I could control ordering.
For example:
configurations {
A
B {
extendsFrom A
}
}
dependencies {
A 'jar1'
B 'jar2'
}
Seems to result in the order of B's path being jar1;jar2
But if I want B to be like A, but override some classes from A, then I need B's dependencies first.
So I was using this approach:
configurations {
A
B
}
dependencies {
A 'jar1'
B 'jar2'
B A
}
Which results in B's path being jar2;jar1
I couldn't figure out a way to get this to work using extendsFrom.
Mainly I tried to use B.extendsFrom(A) with various syntax in the dependencies section but couldn't get that to compile.
Is there a way to get the override/ordering use-case to work using extendsFrom?
I believe it's not possible with extendsFrom.
I am not an expert on the dependencies area, but what could work for you or give you some ideas is something like:
def a = project.configurations.findByName("A")
def b = project.configurations.findByName("A")
b.getIncoming().beforeResolve {
// If you want to get also dependencies from
// configurations that "A" extends use getAlLDependencies
a.getDependencies().forEach{
b.dependencies.add(it)
}
}
Note: getDependencies() and getAllDependencies() don't return resolved dependencies, but just the dependencies that were added to a configuration in build script (e.g. A 'jar1'). If you want resolved dependencies you have to resolve A.
Note2: I don't recommend class shadowing as I think you want to achieve. It can bring a lot of unexpected troubles, e.g. app could compile but might not work at runtime. Maybe you should rather do a dependency substitution or resolve conflicts with capabilities (https://docs.gradle.org/7.2/userguide/dependency_capability_conflict.html#sub:declaring-component-capabilities).

How is an artifact's final dependency scope in a project determined?

With reference to https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
Each of the scopes (except for import) affects transitive dependencies in different ways, as is demonstrated in the table below. If a dependency is set to the scope in the left column, transitive dependencies of that dependency with the scope across the top row will result in a dependency in the main project with the scope listed at the intersection. If no scope is listed, it means the dependency will be omitted.
I can't visualise the above. Please clarify for me on the following points:
First question: Assume A depends on B which in turn depends on C. Which does "a dependency is set to the scope in the left column", "transitive dependencies of that dependency with the scope across the top row" and "result in a dependency in the main project" each refer to in the above example?
Question 2: I have a lib folder which contains compile and provided subfolders. A has a compile dependency on B and a provided dependency on C. B has no dependency. C has a provided dependency on B. Which folder should B be located in?
Transitive dependency can be inferred as
will result in

Incompatible class of models when using the models trained in maven project A to maven project B under the same Maven dependency

I have a big maven project A, where I use weka library to train the models. Now I create another small maven project B using the same maven dependency as A, and want to use the models trained in A.
When I use SerializationHelper class to read the models and use the models to predict for new instance in project B, it encounters some errors like incompatible class of the models(see picture below). I just wonder whether there is a way to use the models trained in A in project B if the maven dependency for A and B is the same. Or I have to retrain the models in B and use it in B. Thanks.
New exception
Classifier cls = (Classifier) weka.core.SerializationHelper.read(model);
double clsLabel = cls.classifyInstance(Data.instance(i));
SerializationHelper is supposed to used for different projects and different machines. Your mistake should be elsewhere. Try following suggestions.
Your project A and project B has different java compiler settings. May be A is 5.0 and B is 8.0.
Your model file is corrupted. Try it first in project where you saved it, Project A.
You are saving different object not Classifier. Try to print out your class name to system.out and see.
Object objModel = weka.core.SerializationHelper.read(model);
String modelClassName = objModel.getClass().getCanonicalName();
System.out.println(objModel);
For Weka classifiers, arff files' headers should be same, exactly same. If your training and testing arff file headers are not same. You will have problems.

Maven inherited attributes from parent POM

I am trying to find an authoritative list of which elements get inherited from a parent POM. Based on this page
When you inherit a POM, you can choose to live with the inherited POM information or to selectively override it. The following is a list of items a Maven POM inherits from its parent POM:
identifiers (at least one of groupId or artifactId must be overridden.)
dependencies
developers and contributors
plugin lists
reports lists
plugin executions (executions with matching ids are merged)
plugin configuration
But when I see the effective POM in one of my projects I see it also inherits inceptionYear, description (which is a problem, this should be a description of the POM that contains it, not of its children. What's the point of all children having a description like "The root of all POMs")
So is there an actual list or does it just inherit everything from the parent pom? i use some of these properties in the artifact's manifest so I want to add meaningful values
The child pom inherits everything from the parent pom. If you need to set meaningful values in the child pom then you will need to override the values in the parent pom.
From the Docs:
When a project specifies a parent project, Maven uses that parent POM
as a starting point before it reads the current project’s POM. It
inherits everything, including the groupId and version number.
Most elements from the parent POM are inherited by its children. Two elements that aren't inherited are artifactId & name. (Also, any plugins which explicitly set <inherited>false)

Maven runtime scope and cyclic dependency

I have two module A and B. Actualy B is plugin to A.
B depends on A in compile time. A NOT depend on B.
On A runtime I want to add B to classpath, so in A's pom.xml I add the following dependency
pom.xml
<dependency>
<groupId>my_group</groupId>
<artifactId>my_Plugin</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
Maven process fail with cyclic dependency error
[ERROR] The projects in the reactor contain a cyclic reference: Edge between 'Vertex{label='A'}' and 'Vertex{label='B'}' introduces to cycle in the graph B-->A-->B -> [Help 1]
[ERROR]
Why runtime dependency impact compile time ?
As suggested by Conan and if possible extract your common code into a separate module in order to resolve the cyclicity. Normally, in such cases one would extract common interfaces and the core classes into a separate module which is extended by both modules which cause the cyclic dependency. You would then remove the direct dependencies on the modules which were initially in a cyclic state. Sometimes this is very hard to solve, but modularizing the code helps you figure out how to refactor your code so that it is easily re-usable.

Resources