I have two projects in java. ProjectA is published into artifactory, and projectAB has jar of projectA as a dependency.
When I make changes in projectA, in order to completely test it, I need to run tests in projectAB (these tests can not be moved into projectA).
What I want is to make changes in projectA, and instantly run tests in projectAB.
Naive schema: change projectA, publish projectA, test projectAB looks too complex.
Idealy for me, I'd like to set in my IDE to override projectA.jar dependency with project A, so I can threat projectA and projectAB as the single project. But I havent found a way to do it.
I use IDEA as IDE and Gradle as a build system
Please consider using Gradle composite builds or Gradle multi-projects that were made exactly for this purpose.
Related
I have a Maven project which has dependency on other Maven projects. I have managed to import those dependency modules via 'project structure' into my project. Able to mvn clean install and able to run the program. Also in my main project, if I were to 'command click ' on a file that is located in the dependency modules, it will nicely go to that .java file (instead of heading to the .class file).
But changes made under the dependency project does not reflect when I run the program. Re building or a new mvn install doesn't make any difference.
For example, I have tried just adding a new variable declaration in a class located in the dependency modules. This variable does not even exist when I run the program and check via debug.
Similarly created an entire method in a class inside the dependency module.
That method doesn't exist either. When I mouse over a breakpoint I placed under this method, I get following message:
No executable code found at line 112 in class com.name....
Information which may help.
This project was working fine without having to add these dependencies cos they existed as jar files as part of this project. Since I needed to make changes in those dependencies, I have removed those jar files 'via Project Structure' and instead imported those dependencies as modules 'via Project Structure'.
As mentioned above, this is working. I am able to build and launch the app. Just not able to see changes when I make them.
Another issue which surfaced and again I don't get it. There was a parameter which was not working on my main project (compilation was failing) until I made the change in my dependency. Now it is working fine in terms of compilation. But when I run it, under debug I get the correct param value, but after the next step, it just jumps to InvocationTargetException. Added short snippet on the code change below.
// Under Main Project
someMethod(Doable do){
// do something
}
DoSomething doSomething = null;
someMethod(doSomething); // compilation error unless I implement Doable
// Under dependency
// implement Doable is the change which compiles now
class DoSomething implements Doable{
//implement something
}
Added the project structure for reference.
Please advice. Thank you.
MyMainProject
mvn_structure
pom.xml
MainDependency
SubDependency1
mvn_structure
pom.xml
SubDependency2
mvn_structure
pom.xml
SubDependency3
mvn_structure
pom.xml
pom.xml
Your project relies on the dependency jars in your maven repo, not on the dependency source codes (the other projects). So in order to have your changes in the other project available to your project, you need to build the other projects first so that their jars in the repo are updated. Only then are those changes available to your project.
I'm looking at options to separate our "mono-repo" so that each deployable service will have its own repo. One disadvantage of this is making changes to any common modules/libraries becomes tedious as it would require publishing the library first and then updating the version in gradle to use the changes.
npm appears to get around this through npm link which would allow you to modify the library and test it in your application before pushing your changes. I was wondering if gradle or any other build tool provides something similar for java applications.
It sounds like composite builds are what you want. The feature allows you to replace a project dependency with another build.
For example, imagine you have an application project called "Acme", which has a dependency on library "MyLib". Acme normally downloads MyLib from Maven Central or your company's artifact repository. But you want to make some changes to MyLib and test them with Acme, so you grab the source for MyLib, make the changes and then use the composite builds feature to run Acme's build with your modified MyLib.
Note that you don't have to manually build MyLib or install the generated artifact anywhere. Gradle will automatically execute MyLib's build and include its artifact in Acme's build.
Hope that makes sense.
I am working on a main project that depends on dbunit. dbunit is defined as a dependency in the Maven pom. It works find, but I found a bug in dbunit and would like to fix it.
Now, I download the source code of dbunit. How can I instructs IntelliJ IDEA and Maven to use that code instead of the maven dependency? Note that my project use subversion, dbunit uses git. My project si Java 1.8 based, dbunit is Java 1.5.
Ideally, I want to be able to simply change the code in dbunit and the hit the compile button in my project, and everything gets compiled and running. I could also debug within my code and then fall into's dbunit's code.
I have wasted an hour trying to import dbunit as a module, but to no vail. dbunit has a parent in the pom.xml that does not correspond to my project and it must remain as such.
So what is the best possible setup to work on both project, one depending on the other?
You need to import both projects (as modules) into a single IntelliJ project.
If you run your code by IntelliJ (but not by using Maven goals), it will use the dbunit module, instead of using the artifact in your repository.
Modules in your IntelliJ projects can be completely unrelated, it does not matter which parents they have.
I couldn't really find an answer anywhere to this particular question.
I have a (Maven) project consisting of multiple modules, let's say a core module (a jar) and a webapp module (a war).
When I run mvn clean package on my webapp, does it automatically always build the core first and will it pick up any changes in it? Do I have to run mvn clean install instead? Or do I have to run mvn clean package/install on my parent pom?
Does it matter if the parent/module is a release or a snapshot?
If you are working with a so called Multi Module Build you should do everything what you like to do with your whole project from the parent level.
There you can do:
mvn clean package
than it will build all modules in the correct order (assuming you have defined the dependencies between them correct).
If you have such a multi module build all your modules incl. your parent should have the same version number. If you like to make a release of the whole you can simply start from the parent.
You have to build anything that's changed, upwards. So, if you change core, then rebuild core, then rebuild your war. If you've just changed your war, then you only need to rebuild your war. Cleaning is generally good practice. The reason not to do it would be if you're generating a bunch of entity classes, which takes a long time to redo.
I've seen a lot of mistakes because people forget to clean, and then some old piece of code is still active, even though they thought they'd deleted it.
Installing will put your latest build into your M2 repo, which is generally a good idea too. You really can't go wrong with "mvn clean install"
Our software is written in Java and comprise many (7) projects.
These projects are Netbeans ant projects.
I'm considering to converting them to maven2.
Where can I find some hints for doing such thing?
Don't read that book. It will only make you confused. Read this book instead: "Maven - The definitive guide" http://www.sonatype.com/books/maven-book/reference/ .
Also, the maven site has a lot of information, but the structure is terrible so you'll need to use google to navigate in it.
Here is my suggestion:
Do this by hand, not with "automagic" "help" from the IDE. Maven integration doesn't work that good yet, not in any IDE.
Make sure you program project is divided into modules under a common umbrella module, so that each module produces a single binary artifact (jar, war,...) possibly accompanied by the javadoc of the source code behind that artifact, a zip with the source code etc. The basic principle is that each module produces a single artifact, containing all the non-test-code under that module. You can do this while the project is still built by ant.
Each module should conform to the standard maven directory layout. The build destination is under [module]/target/[output-type, e.g. "classes"]. The source code is under [module]/src/main/[src-type e.g. "java"] and [module]/test/[src-type]. The artifact consists of all the code under src/main, and none of the code under src/test, as it built to the target directories. You can do this while the is still built by ant.
Start by transforming the sub-module that has no dependencies on other modules in the project.
Now you can create the parent maven module pom.xml with artifact type "pom", consisting of one of the modules below. Make a child module for the first submodule (the one with only external dependencies), using the umbrella module as "parent". Remember that you need to specify version for the parent. Remember to add the child module as a "module" in the parent too. Always use ${project.version} as version in the child modules when you create multi-module projects like this. All modules under a parent must be released simultaneously in a single operation, and if you use this setting maven will make sure the version fields stay the same across all modules and gets updated everywhere during the release. This may make it difficult to re-use the existing numbering scheme, but that doesn't matter. You are never going to run out of version numbers anyway.
Add the necessary dependencies, and make sure you can build the parent and the child module together using the command "mvn clean install" from the parent module.
Proceed with the rest of the modules the same way. Dependencies to other modules under the same parent project should also use ${project.version} as the "version" they are depending on, meaning "the same version as this". NOTE THAT in order to build, the module you are depending on must be built using "mvn install", so that it gets deployed to you local (computer) repository. Otherwise the depending module will not be able to find the classes. There are NO source-code dependencies between modules in maven, only dependencies to built and packed versions installed in local and remote repositories. This can be very confusing if you come from ant-projects. Build from the root module until you get comfortable with this. It takes two days.
Don't use maven integration in IDEs. It is a bad idea. Use "mvn idea:idea" or "mvn eclipse:eclipse" to set up your workspace as a non-maven ordinary IDE project. The inter-module dependencies mechanisms in maven and the IDE aren't identical and will never be. Also, if you have several mavenized projects with dependencies in between, you want to have several of these in your workspace with dependencies set up between. You can do this with mvn idea:idea / eclipse:eclipse if you create a separate maven project file called "workspace.xml" (or whatever) in the same directory as parent module, set up as a multi-module project containing modules "." and "../otherproject" (only one-way reference here, no parent ref back). If you run "mvn idea:idea / eclipse:eclipse -f workspace.xml" you get a workspace with all these modules linked together. No IDE integration lets you do that. This sound like a lot of extra work, but the workspace.xml-file is really small. It doesn't have to contain all that dependency stuff and all that, only the reference to the modules you want to bind together in your IDE.
I did a succeful migration of NetBeans Ant project to Maven project using the instruccions by Joseph Mocker here: http://forums.netbeans.org/ptopic55953.html
I cite the important part:
close the project
rename the build.xml, nbproject files/folders to something so NB won't recognize them.
close and restart NB (so any memory cache knowledge of the project is gone)
copy in an empty pom from some other project.
open the project back up in NB (NB should now identify it as a maven project)
rearrange the files to follow the maven way (™)
This won't be an easy task since Maven2 expects the files to be organized in a specific way. Anyway Better Builds with Maven is a free book that should get you started. It will help you understand Maven and it also has a chapter on migration.
I discovered that the migration is not necessary. The real requirements that I need was automatic download of dependencies (libraries).
This is also achieved by Ivy which nonetheless uses maven repositories.
I solved converting project from ant to ant+ivy with IvyBeans.
I have built a script to migrate Ant builds to Maven. You can find more information here:
https://github.com/ewhauser/ant2maven
It won't help you with fixing your directory structure and or any additional Ant tasks, but it removes a lot of the tedious steps to get started.