I've recently tried to work with NetBeans and I don't understand how it handles Maven multi-module projects.
My project has fairly complicated modules structure and when we're working on it (we mainly use IntelliJ community edition) we don't want to open all its modules (~50 modules) because it will take hours to load the project, instead we've created a 'workspace' module: a folder with pom.xml that has a packaging type pom and defines modules that I would like to load.
Lets say it defines modules A, B, C.
We have our main method (we don't use any type of container) in module A which is a low-level infrastructure module.
As a runtime dependency we need A, B, C. But A doesn't really depend on B, C, but rather B and C depend on A (in terms of Maven dependencies).
So we've created another module, lets call it runner, where we define all the dependencies. Our workspace pom.xml has module declaration of runner, so in order to run the project from IntelliJ, we use a 'classpath of module runner' while running method main in module A.
Now, How can I achieve the same affect with the latest Netbeans (7.1.2)?
I understand that question is kind of newbie's style, but I struggle with it a lot of time with no luck.
Just struggled with the same issue - from what's listed in the Netbeans wiki it seems that every module represents it's own Netbeans project and everything else would be expressed with project dependencies. See http://wiki.netbeans.org/MavenBestPractices
A project with modules is known as a multimodule, or aggregator project. Modules are projects that this POM lists, and are executed as a group. The Maven projects in NetBeans lists these modules as "Required Projects". So you will only get the required projects list populated for Maven projects with "pom" packaging that have modules defined.
Related
From Jigsaw Project:
Make it easier for developers to construct and maintain libraries and
large applications, for both the Java SE and EE Platforms.
I'm trying to learn what project Jigsaw is and till now it seems that the goal of Project Jigsaw somewhat overlaps with what we did using Maven (or Gradle) dependency management:
Is it a threat to build tools like Maven?
Or my understanding is wrong and project Jigsaw is going to complement these build tools in some way?
Very simplified answer
After Jigsaw, public will be public only within the JAR scope. To see the class outside the JAR it must be exported.
Java will force modularization because any inter module interaction will have to be specified in the module-info file.
For example, if you produce a WAR it will remain almost unchanged but all JARs packages in the WAR must define a module-info (or not define it and be treated as automatic or unnamed modules).
Maven has 2 main features: dependency management and building:
Dependency management means Maven can determine versions of libraries
and download them from repositiories.
Building means Maven can compile code and package it into artifacts.
To conclude: Maven will still be responsible for building, but one must learn how to compile and package using Jigsaw modules.
Modules are not in any way a threat to build tools. Modules complement build tools because build tools construct a dependency graph of artifacts and their versions at build time while modules enforce dependencies of artifacts/modules (not including versions) at build time and run time.
From the State of the Module System:
"A module’s declaration does not include a version string, nor
constraints upon the version strings of the modules upon which it
depends. This is intentional: It is not a goal of the module system
to solve the version-selection problem, which is best left to build
tools and container applications."
The ultimate goal is to find out a way to functional test a library.
I have a parent project A with sub modules B,C and D.
Let us assume that the module C has a dependency on module B (B being the library) and is included as a maven dependency using the <dependency> tag.
I am just curious to know when I start up the application server say Tomcat would a jar for B (along with others) be created and then C uses this jar?
I tried to monitor my directories to see whether jars were being created every time the server was started up but that doesn't seem to be the case.
If B isn't used as a jar then it would not exactly be a FT since the ultimate goal is to be able to use B as a library in other projects as well. I feel like this shouldn't be a problem since the code itself does not change but I'd like to get some insight into the same and comments if any. Thank you !
I hope I get it right, because you seem to mix building, deploying and testing
Maven will only build the current pom. It will not build dependency libraries but expect to find them in the repository.
Only if module A is a multi-module build, then B, C and D will be built when you build A.
Starting a tomcat will not trigger any build.
For a functional test you would build, package and deploy and execute your tests against the full application.
I have 2 projects, Project A and Project B. Project A is a Play2 App that depends on Project B (which is a client library.) Currently Project B is pulled from our artifactory with SBT. I would like to set up IntelliJ such that Project B is pulled from the project source on my computer, rather than from the artifactory that is specified in.
I have added Project B as a module of Project A and added Module B to the dependencies of Module A. I then ordered Module B to be at the very top of the dependency list. The static analysis of the code seems to be working fine, there's not compilation errors showing when I updated Project A's code to use a new method signature that I've updated in Project B. However, when I run the Play App I get a compilation error stating that the method signature is incorrect.
Is there a way to override the module used at runtime for SBT and the Play App?
You can do this via sbt. In your build.sbt, for example:
val localDep = ProjectRef(file("/Users/me/projects/b"), "b")
dependsOn(localDep)
IntelliJ will import this dependency as a module. You should remove the library dependency however, to avoid conflicting classpaths.
Naturally, this makes the project hard to share unless other developers have the project in the same location. In that case, I would create a multi-project build instead, which is usually the best choice for tightly coupled projects with individual resulting artifacts.
Another option is a git project dependency:
val projectDep = ProjectRef(uri("git://github.com/me/b"),"b")
Let's say I have a maven project which has some maven modules inside.
My main module depends on the other modules, so when I compile the main module they should be compiled together.
The question is, how to add these modules as dependencies to the main module?
I know if I have a custom lib that I want to use with maven, let's say a utilities project, I have to compile the jar of the project, do a mvn install:install-file on it to install it on the local repository and then add it to the pom.xml.
Do I have to do this with all my modules and add the dependency to the pom.xml on my main module? Because if it should be done like this, there will be a lot of work to do when changing code on the other modules.
What is the best practice to use avoid the trouble of compiling/installing the modules to local repository?
The question is, how to add these modules as dependencies to the main module?
The same way you add any other dependency to your maven project. By adding group id, artifact id and version to <dependency> element
Do I have to do this with all my modules and add the dependency to the pom.xml on my main module?
If your main module depends on some module A then only the pom of the main module should contain dependency declaration towards module A. You do that for all the dependencies of your module.
I don't know what you mean by "a lot of work when changing the code on other modules". Maven has nothing to do with code changes, it just builds the projects whatever they look like at the given moment...
What is the best practice to use avoid the trouble of compiling/installing the modules to local repository?
Any project that you invoke mvn install on gets built and it's jar copied to local repository. That's all you need to do to get the jar into the repo. This will also put all the dependent jars, if available, into the local repo.
As for best practices for multi module projects:
If your parent project (the one that has modules inside) has <modules> section that lists the modules of your application, and modules are in subdirectories of your parent project, then you simply mvn install (or whatever you want to do) the parent project and that will cause all the modules to be built in order defined by declared dependencies between them. That means that if your main module has dependency on module A, then module A will be built before the main module. This way you can build and install all your modules with one command. On the other hand this approach makes more tight coupling between modules which is not desired in some cases, so it depends on your use case whether it is a good approach or not.
In my project, we are given a sample project structure to be followed and I am very new to multi-module projects.
We have a parent project and 4 sub-projects that have that as parent.
And in the parent project, only 3 out of those 4 are configured as modules.
What's the difference/significance in having a project as a child but not as a module to the parent project?
Other than dependency management, what do we achieve by using multi-module project hierarchy?
1) The "parent-child" relationship helps to manage dependencies. Say in your company(or project), you have some common libs that nearly all projects(or sub-projects) need to depend on, or you have a standard build configuration. You'd better put these common dependencies and build config in your parent pom, so that all children can inherit from parent. This is quite like inheritance in OOP.
2)If a project can be divided into many modules, and these modules highly couple with each other. Which means in most cases they are modified and build together, and none of them can be taken apart as a library for other projects. Then you can declare them as modules of a multi-module maven project.
But personally, I don't quite recommend multi-module maven project since it not flexible and more complex to build and to work with IDE,CI or other tools.