Maven requires manual dependency update? - java

I'm new to Maven, using the m2e plugin for Eclipse. I'm still wrapping my head around Maven, but it seems like whenever I need to import a new library, like java.util.List, now I have to manually go through the hassle of finding the right repository for the jar and adding it to the dependencies in the POM. This seems like a major hassle, especially since some jars can't be found in public repositories, so they have to be uploaded into the local repository.
Am I missing something about Maven in Eclipse? Is there a way to automatically update the POM when Eclipse automatically imports a new library?
I'm trying to understand how using Maven saves time/effort...

You picked a bad example. Portions of the actual Java Library that come with the Java Standard Runtime are there regardless of Maven configuration.
With that in mind, if you wanted to add something external, say Log4j, then you would need to add a project dependency on Log4j. Maven would then take the dependency information and create a "signature" to search for, first in the local cache, and then in the external repositories.
Such a signature might look like
groupId:artifactId:version
or perhaps
groupId:artifactId:version:classifier
This identifies a maven "module" which will then be downloaded and configured into your system. Once in place it adds all of the classes within the module to your configured project.

Maven principally saves time in downloading and organizing JAR files in your build. By defining a "standard" project layout and a "standard" build order, Maven eliminates a lot of the guesswork in the "why isn't my project building" sweepstakes. Also, you can use neat commands like "mvn dependency:tree" to print out a list of all the JARs your project depends on, recursively.
Warning note: If you are using the M2E plugin and Eclipse, you may also run into problems with the plugin itself. The 1.0 version (hosted at eclipse.org) was much less friendly than the previous 0.12 version (hosted at Sonatype). You can get around this to some extent by downloading and installing the "standalone" version of Maven from apache (maven.apache.org) and running Maven from the command line. This is actually much more stable than trying to run Maven inside Eclipse (in my personal experience) and may save you some pain as you try to learn about Maven.

Related

Installing a framework without maven or gradle

I try to install Javalin framework for creating an API on my Java project. (old java 8 project without maven, gradle, etc). I would like to install the framework with adding the jars to my build path.
But If I add the main jar file then it needs another dependencies jar , then another one another one another one.. etc.
Is there any simple way to add this to my project and all it's dependencies without any build tool like Maven,etc?
I have tried adding it manually , but each jar has many dependencies that it is almost impossible(?)
Well you could create a Maven project and use it to download the dependencies for you.
Maven dependency plugin might be useful. With it you could just call:
mvn dependency:copy-dependencies
and it will download all your dependencies into target/dependency.
I don't think there's a way, I'm afraid.  Dependency management is the exact problem that build tools like Maven and Gradle were created to solve!
The framework supplier could provide a ‘fat’ jar including all the dependencies; but I'm not aware of any that do, as everyone uses Maven or Gradle (or SBT or Ivy or Grape or Leiningen or Buildr).
I think the only real alternative is to do it manually — which, as you've discovered, can be a horrible and lengthy task if the dependency tree is big.  (And would need redoing with every update.)
So I'd suggest biting the bullet and using Maven if you can.

Including .jar files in Github for consistency

I am new to using github and have been trying to figure out this question by looking at other people's repositories, but I cannot figure it out. When people fork/clone repositories in github to their local computers to develop on the project, is it expected that the cloned project is complete (ie. it has all of the files that it needs to run properly). For example, if I were to use a third-party library in the form of a .jar file, should I include that .jar file in the repository so that my code is ready to run when someone clones it, or is it better to just make a note that you are using such-and-such third-party libraries and the user will need to download those libraries elsewhere before they begin work. I am just trying to figure at the best practices for my code commits.
Thanks!
Basically it is as Chris said.
You should use a build system that has a package manager. This way you specify which dependencies you need and it downloads them automatically. Personally I have worked with maven and ant. So, here is my experience:
Apache Maven:
First word about maven, it is not a package manager. It is a build system. It just includes a package manager, because for java folks downloading the dependencies is part of the build process.
Maven comes with a nice set of defaults. This means you just use the archtype plugin to create a project ("mvn archetype:create" on the cli). Think of an archetype as a template for your project. You can choose what ever archetype suits your needs best. In case you use some framework, there is probably an archetype for it. Otherwise the simple-project archetype will be your choice. Afterwards your code goes to src/main/java, your test cases go to src/test/java and "mvn install" will build everything. Dependencies can be added to the pom in maven's dependency format. http://search.maven.org/ is the place to look for dependencies. If you find it there, you can simply copy the xml snippet to your pom.xml (which has been created by maven's archetype system for you).
In my experience, maven is the fastest way to get a project with dependencies and test execution set up. Also I never experienced that a maven build which worked on my machine failed somewhere else (except for computers which had year-old java versions). The charm is that maven's default lifecycle (or build cycle) covers all your needs. Also there are a lot of plugins for almost everything. However, you have a big problem if you want to do something that is not covered by maven's lifecycle. However, I only ever encountered that in mixed-language projects. As soon as you need anything but java, you're screwed.
Apache Ivy:
I've only ever used it together with Apache Ant. However, Ivy is a package manager, ant provides a build system. Ivy is integrated into ant as a plugin. While maven usually works out of the box, Ant requires you to write your build file manually. This allows for greater flexibility than maven, but comes with the prize of yet another file to write and maintain. Basically Ant files are as complicated as any source code, which means you should comment and document them. Otherwise you will not be able to maintain your build process later on.
Ivy itself is as easy as maven's dependency system. You have an xml file which defines your dependencies. As for maven, you can find the appropriate xml snippets on maven central http://search.maven.org/.
As a summary, I recommend Maven in case you have a simple Java Project. Ant is for cases where you need to do something special in your build.

Maven compile dependency instead of taking it out of the local repo

I am sorry i don't know maven good enough for the complex environment i am currently working in (1k+ applications, most of them are Java EE). I still give it a try to describe what i want to archive:
0.) There is a company framework that abstracts the Java EE World a bit and is used in all the Java EE components
1.) I checked out the maven project of the Java EE component i am working with
during the build it downloads the dependencys of other components out of the companys repository and stores it inside my local repo for compilation. So i can see the jar-files of the companys framework inside my local repo.
2.) I now want to change some of the frameworks functionality for a local test so i checked out their sources from another SVN repository. I made the changes and build that framework component with maven "clean install".
3.) I rebuild the component i am working with as well.
Inside eclipse i can now click on one of a frameworks classes method and it opens the according source. But this only happens because the local repo is meant to contain source-jars for any dependency as well. So in my editor i can see this source is from the jar of the framework in my local repo and i cant change anything.
Could someone please give me a hint how i can archive the following:
I can make changes to the framework (and build the frameworks jars with "clean install")
I can build my component and it uses the above compiled framework jars rather than the "old" ones from the local repo.
I will right now start to read the entire maven documentation and each and every section (i try to understand that dependency management since 1 year and still don't get it) but i would really appreciate if you could help me out a bit here.
I don't know how Eclipse manages maven dependencies, but
In IntelliJ IDEA this is simple - if maven dependency is in project then IDEA uses it instead of dependency from local repo.
So if u want to edit framework source code and use this changes immidiately - i think that framework should be in your Eclipse Workspace. And your module in Eclipse should reference framework artifacts directly - not over Maven dependency mechanism.
I think that this is a Eclipse Maven plugin responsibility. Do u have any installed Maven plugin for Eclipse? (M2Eclipse for example)

Apache Maven: where do dependencies and libraries installed locally up?

I'm building a Java project that has a dependency on a library. mvn.bat clean install produced the target subdirectories as expected, and the project built fine with mvn.bat clean install as well.
What's not expected is that when I deleted the entire directory of the library, the outer project still built fine, although the library it depends on was gone.
How does this work?
UPDATE: Turns out Maven makes some sort of cache in %USERPROFILE\.m2.
You are most likely thinking of your local repository where everything you install locally (and maven downloads for you from the central repository) is put for later usage.
The behavior you describe is intentional, and allows for building A once and then let B reference it whenever needed, without having to recompile A every time. This is usually very desirable, especially in teams or with large code bases.
Note, that for changing code you should be using -SNAPSHOT artifacts. They are treated slightly differently.
Your dependencies are always downloaded into .m2/repository.
If you want to have some predictability on downloaded libraries in your team, you can put in place a repository manager like Nexus : https://repository.apache.org/index.html#welcome
Instead of downloading dependencies from Maven central, your developers will download their dependencies from this repository manager.

Is there any disadvantage to putting API code into a JAR along with the classes?

In Java if you package the source code (.java) files into the jar along with classes (.class) most IDE's like eclipse will show the javadoc comments for code completion.
IIRC there are few open-source projects that do this like JMock.
Lets say I have cleanly separated my API code from implementation code so that I have something like myproject-api.jar and myproject-impl.jar is there any reason why I should not put the source code in my myproject-api.jar ?
Because of Performance? Size?
Why don't other projects do this?
EDIT: Other than the Maven download problem will it hurt anything to put my sources into the classes jar to support as many developers as possible (maven or not)?
Generally because of distribution reason:
if you keep separate binaries and sources, you can download only what you need.
For instance:
myproject-api.jar and myproject-impl.jar
myproject-api-src.jar and myproject-impl-src.jar
myproject-api-docs.zip and myproject-impl-docs.zip
Now, m2eclipse - Maven for Eclipse can download sources automatically as well
mvn eclipse:eclipse -DdownloadSources=true -DdownloadJavadocs=true
Now, it can also generate the right pom to prevent distribution of the source or javadoc jar when anyone declare a dependency on your jar.
The OP comments:
also can't imagine download size being an issue (i mean it is 2010 a couple 100k should not be a problem).
Well actually it (i.e. "the size) is a problem.
Maven suffers already from the "downloading half the internet on first build" syndrome.
If that downloads also sources and/or javadocs, that begins to be really tiresome.
Plus, the "distribution" aspect includes the deployment: in a webapp server, there is no real advantage to deploy a jar with sources in it.
Finally, if you really need to associate sources with binaries, this SO question on Maven could help.
Using maven, attach the sources automatically like this:
http://maven.apache.org/plugins/maven-source-plugin/usage.html
and the javadocs like this:
http://maven.apache.org/plugins/maven-javadoc-plugin/jar-mojo.html
That way they will automatically be picked up by
mvn eclipse:eclipse -DdownloadSources=true -DdownloadJavadocs=true
or by m2eclipse

Categories