Using IntelliJ IDEA, it is often a straight-forward task to check out a project from GitHub and get it to build locally.
Once the base project is imported from GitHub, the IDE will download artifacts which will allow the main project to run. The dependencies can be examined by using File > Project Structure... > Libraries
.
So the IDE downloads dependencies to allow running, but not to build from source. The IDE is able to decompile classes, but the IDE will not automatically download the source code for those dependency libraries so that the programmer can alter the code.
This question is about the steps required in the IDE and project configuration such that a selected dependency will be built locally, and thus allow the programmer to alter the code.
What I tried was to import the project on which the main project was dependent, as a separate project, then configure the main project to utilize the local project instead of the downloaded artifact. The first step, downloading the sub-project and getting it to compile, was completed successfully.
So I ended-up with two projects, the main one, and the one on which the main project depended. The task at hand, if this was the appropriate way to get this done, would be to open the main project and take some action to convince the main project to use the local build, rather than the downloaded runtime "jar".
First, I edited the POM.xml
to comment out the dependency for the sub project. Checking File > Project Structure... > Libraries
, I could see that it was gone, and the build now failed (as expected).
I went to File > Project Structure... > Libraries > (plus sign)
and poked around with New Module
, and Import Module
, but I was not able to convince the original project to use the locally available sub project. The result from various attempts was that code in the base project was not able to import from the sub project (unable to compile).
What are the specific steps to take in the IDE to get what was a runtime dependency "jar file" to instead to build locally, and use that instead?
CodePudding user response:
Use a SNAPSHOT
version for the dependency (you'll need to change this in both your project's pom.xml
and the dependency's pom.xml
, so if the current version is 2.0.0
change it to 2.0.0-SNAPSHOT
)
Then you can edit the dependency's code and run mvn install
in the dependency to provide the new version of the dependency to your project.
CodePudding user response:
TLDR: there is no simple and straight-forward way of downloading a project's code and the code of its dependencies to rebuild it in one go as a complete chain.
Your project depends on several other artifacts. From the screenshot, we may assume that this is a maven project, at least we can be sure that there artifacts with compiled classes available for download, because this happends during build. You can view the compiled classes of your dependencies, because Intelli has the capability of decompressing jars and decompiling code, obviously, but the contents you are viewing is read-only.
Sidenote: Maven convention is to create 3 separate jars for each project. One with compiled classes, one with source files only and one with generated documentation. By default intellij may not download these, but you can force it (right-click on pom.xml -> maven -> Download sources and documentation
). This will attach the actual source code instead of decompiled classes to your IDE, so it's much easier to understand the code - but still, there is no option to modify it - it's still read-only extract from some jar.
So what if you want to actually edit the source? You have 3 options, all with its own set of problems that need human intelligence to solve:
- You extract the decompiled source from classes jar
- You extract the attached source from sources jar
- You check out git repository of the dependency
Now, beware of the downsides of each approach:
You can be sure that the decompiled source matches your project dependency 1:1. But decompiled code is not easy to read, missing comments, etc. Also, some projects may not ship their build scripts with the classes jar. Anything more complex than
mvn clean install
may turn out to be a blocker.You can be reasonably sure the code matches your project dependency, but this actually is not a given. There is a chance of human error, causing the sources to actually not match the compiled classes (build from different revision or whatnot). Much depends on the quality of the project, the discipline put into the build process and care to avoid environment specific configuration that is not part of the source. The larger and older is the project, the less chances are you are able to recompile it successfully using only src jar.
A sane man's approach. You should have your build scripts, readmes, tutorials, etc. Except, of course, if we are talking some obscure company internal project with zero effort put in its maintenance. Surely, there are the same issues as before: not all projects are rebuilt easily on any environment. There may be steps upon steps required for your workstation to be configured as expected. Hopefully, self-respecting open-source java projects are easy to build, but again - not a given - not all project are open-source, not all are self-respecting. Important note: When checking out the git repo of your dependency - you must also make sure that you are using correct revision. If the project is maintained with respect for git tags/branches naming convention - you are in luck. Not a given by any means.
All the above is enough to discourage any attempts to automatically decompose dependencies to compilable units by your IDE, and all the burden is put into you. So let's assume the best - our dependency is a simple, self-contained java application that is easily built using simple mvn clean install
. You have it checked out in a separate project in your IDE. You identified correct git revision that matches version your project depends on.
Now let's apply your little change and test it. First thing you want to do is change pom.xml of your project to use a made up version of your dependency. It should be a -SNAPSHOT
version for clarity and tidiness. You may of course build your modified dependency with real release version - but please be wary of how maven manages dependencies. If you install version 1.0
yourself - it stays in your local repo forever. You will forget about it, and will be using your fake 1.0
version when building all other dependent projects unless you manually locate and remove it from repo. So stick to 1.1-SNAPSHOT
.
Now every time you need to apply a small fix to your dependency, execute mvn clean install
in its repo, then make sure your actual project depends on the correct new SNAPSHOT version, execute your maven clean install
and that's it.
Note that all this has very little to do with Intellij. You are not expected to modify any library paths, advanced project settings, or links to jars. Stick to modifying pom.xml and you are set.