Unable to resolve gradle dependency in a multiproject hierarchy - java

root project (settings.gradle)
|
|---- projectA (Pojo Class A.java)
|
|---- projectB (Libraries B.java)
|. implementation project(':projectA')
|
|---- projectC (Requires A.java and B.java)
compileOnly(project (':projectB'))
Hello Guys, this is the multiproject structure that I have
Project A (lambda layer) - Has few POJO class for ex. Has A.java
Project B (lambda layer) - Has Libraries and Also has B.java
build.gradle (plugin:java and dependencies has implementation project(':projectA'))
--In project B I am able to access the class of project A, A.java. this is as expected.
Project C (AWS Lambda Function) -- Project C requires the class from Project A and also from project B only for the compiletime.
Since project B runtime already has A.java and B.java, and also as Project A and Project B will be lambda layers and not to be included in the lambda runtime.
I have done
build.gradle (plugin ('java') and compileOnly( project (':projectB'))
Now in project C : I am only able to access B.java but not A.java. Why is it omitted as it was in the runtime classpath of project B??
How should i keep the structure of overall projetcs / project C to access A.java ??

Related

Jenkins looking for dependency project package files in its own folder for multi module projects

I am working on multi module project with one parent and 2 chils. . A is parent , B and C are child modules.
B is dependent on C.
The project build is success locally.. but in jenkins Build is success for only parent and child module C and its failure for module B.
For module B which is dependent on C, its checking the file imports of C in package B.
EX: import com.example.C.config.appconfig;
Jenkins is checking that file as "B/src/java/AppConfig"
But it should check as the "C/src/java/AppConfig"
As the build is success for A and C respositories they are pushed Nexus Artifacts as well, but still its recognising the same way.Please suggest.

Put jar output from one module into another

I have Gradle 7 project, there are two sub modules
- Root
- sub project A
- sub project B
My goal is following:
When project A is build it creates a A.jar file.
When project B is build it creates a B.jar file that contains unexploded A.jar output from build of project A
To be more clear B.jar should look something like this
\META-INF
\my
\package
\tree
SomeClassInsideBJar
\A.jar
URI aJarUri = someClassInsideBjar.getClassLaoder().getResource("A.jar");
Subproject A build just fine, but i cannot figure out how to embed its jar into B.jar
According to another questions I should be able to get a reference to .jar output of a task by .archiveFile property
I tried this in B`s build file
jar {
sourceSets.main.resources.includes = project(":A").getByName("build").archiveFile
}
But that ends with error
No signature of method: build_62kfcng7dpn0plap6jwx8ojvt.jar() is
applicable for argument types:
(build_62kfcng7dpn0plap6jwx8ojvt$_run_closure2) values:
[build_62kfcng7dpn0plap6jwx8ojvt$_run_closure2#be2d508]
Let's say you want to include classes and resources project A to B
The module B should contain:
dependencies {
// it must be compile only to prevent it to be exposed as a transitive dependency in the pom file
compileOnly project(":A")
}
jar {
from project(':A').sourceSets.main.output
}
Then you shall expect when you generate a jar with jar task inside the B.jar classes from module A right next to the classes from B, e.g. modules are merged.
Gradle 7.6.0
If what you need to do is to reference the project A inside project B, then you can compile project A at the time of project B build time and add it as a dependency to the project B jar file.
include both projects in settings.gradle file in the root project.
include 'project A'
include 'project B'
then in the build.gradle file of project B add
dependencies{
compile (':project A')
}

Handling interdependencies in maven multi-module project

I'm been going through the Maven Framework. While going through multi-module projects, I read that cyclic dependency is not acceptable among the modules.
So I thought of a scenario, something like...
root ----------
- pom.xml |
|
|--- moduleA
| - pom.xml (moduleB has been added as a dependancy)
|
|--- moduleB
- pom.xml
Assume that moduleA has a property class AppProperty and a Main class which invokes another class B available in moduleB
Main class available in moduleA :-
someValue = AppProperty.get(propKey);
//some logic
B mb = new B();
B.process(...);
Class B of moduleB :-
process(...) {
someOtherValue = AppProperty.get(someKey)
// some other logic
}
Now Main will not throw any compile-time errors as its dependancies have been resolved because moduleB has been added as a dependancy in moduleA'a pom.xml. But for class B that is not the case as its invoking AppProperty class which is available in moduleA only. I cannot add moduleA's dependancy in moduleB's pom as that would lead to cyclic dependancy (if I understand it correctly).
I understand that ideally it is advised to maintain codes in an acyclic manner, but what if because of some reason removing cyclic dependancy is just not feasible? In such a scenario, is there any way to handle cyclic dependancies without actively changing the existing code logic?
You cannot build a project with cyclic dependencies. You need to build B before A before B, which is kind of a contradiction.
But problems like yours are easy to solve:
If the problem is just the class AppProperty or a few others, just move them from A to B.
If you have some common classes for A and B, create a helper module C and use it as dependency in A and B.
If A and B call each other all of the time, they should probably be just one module. So merge them to one module.

Java 9 - Cannot be resolved as a module

Very simple use case, I am using Eclipse Oxygen 4.7.3a that includes support from Java 9. I have two projects that are Java 9 projects:
- projectOne
| - src
| - module-info.java
| - com
| - package1
| - first
| Classificator.java
- projectTwo
| - src
| - module-info.java
| - com
| - package2
| - second
| Classifiable.java
I want to use the Classifiable class inside the Classificator, so I try to import the second module into the first project.
module-info.java Project 1:
module projectOne {
requires projectTwo;
}
module-info.java Project 2:
module projectTwo {
}
Eclipse is giving me the error:
projectTwo cannot be resolved to a module
Do I have to gather all my Java projects under one "main project" in order to let Eclipse know that all those modules are usable inside it? Or have I missed something else?
No, you don't need them to be in the same directory. Ideally, your project-one module defines some uses, which are implements by your project-two module (or vice-versa). Get the runtime implementation of your used interfaces. For this, both jars/classes must be on the module path.
For further information on module build, multi module builds,... you can refer to this link. Even if you do not use gradle, its tutorial on java 9 module build is quite interesting and gives some insight.
While wiring as a service is certainly a viable approach (as described in the other answer), let me add that requires can be made to work, too, of course.
The thing that was probably missing from the first approach is: Eclipse still needs to know where to look for modules. In real world projects this will typically be mediated by your build tool of choice plus a plug-in like m2e or buildship.
If no such plug-in is used, a normal project dependency should be added to the Build Path of project projectOne in order to make project projectTwo visible. Once the project is on the Build Path the module defined by the project can be resolved in references in module-info.java.

Inheritence conflict between java ant projects

I have two Java projects, built with ANT, named Project A and B which I created in Luna Eclipse (the Java EE version). The package structure is as follows:
Project A
|
src
|
SomePackage
|
A.java
Project B
|
src
|
AnotherPackage
| |
| B.java
|
SomeOtherPackageInSrc
|
C.java
where A, B, and C are non-abstract POJOs. I also have the following inheritence structure:
C extends B, B extends A.
I added a public method to A, so that its children could have it. I then built project A, and added the resulting JAR to the project B's Build Path. I noticed that C could not access the new method. I then attached the source JAR to the build path, viewed the the source for A.java, and the newly added method was present. I tried a number of things, and adding project A to the Deployment Assembly of project B allowed C to see the new method from A. Why does simply extending the class and adding the jar in which the extended class lives not provide visibility to public methods in this case?
I suppose, only extending and adding the project to your classpath will make it compile, but it is not automatically in the resulting deployment unit (EAR/WAR). ANd this makes the classes unavailable at runtime.
I found the problem. I had multiple versions of the Project A JAR on my classpath, and the compiler picked up the old JAR instead of the new one. Rookie mistake.

Categories

Resources