What is Maven in Android Studio? - java

There are lot of Answers on how to use Maven in Android and work with it.
However, As Gradle being already available, which manages the build process of Android projects and support complex scenarios in creating Android applications, such as Multi-distribution and Multi-apk,
What exactly is the role of Maven in Android Studio?
And how is it different from Gradle?

The short answer is: The tools do the same thing but in different ways. The difference is how you can use them to build your project. Apache Maven goes for "follow our convention" way and Gradle gives you flexibility. Some devs don't want a new tool or don't have time to learn how to use it properly.
Now the long answer...
To understand properly why some devs are attached to Apache Maven, we have to look at some years in the past.
Apache Maven is a build automation tool just like Gradle.
Maven got released on 2004. Gradle first version got out on 2007 but it did not become as popular as Maven in the early days.
Some devs don’t like having to learn anything new and most companies don't want to risk the exchange of an already running and mastered tool (Maven) for the new kid on the block.
Gradle became popular when the Android development raised. Android's project has a different project structure from Java EE/Web projects. Trying to use Maven on Android's project just feels unnatural, the tool was not prepared to provide flexibility.
Until now, Apache Maven can be used on simple Java EE projects without being a pain in the ass if you already know the forced conventions. So devs that aren't aware of Gradle/did not get in touch with Android apps don't have motivation to change to another tool.
In my opinion, Gradle is better than Apache Maven in every way that you could imagine. It gives you flexibility and tries not to get in your way, a "feature" that you cannot find in Apache Maven. If you don't follow Apache Maven life cycle, your build will fail, that's it.
For example, your code can be spread across many directories in any kind of layout if you are using Gradle. If you are on Maven and you don't follow the 'convention', you'll lose some hours changing your pom (Maven's build file) to be able to understand and handle your folder structure.
E.g.: Java source code must be on src/main/java folder. If you got an old project and the structure is src/java, sorry, You have no guarantee that all Maven plugins will run as expected.
Gradle does us a favor and puts more features for comparison in a very organized chart. Take a look. https://gradle.org/maven_vs_gradle/

Maven is just a tool that manages and simplifies how you build your project. Among many other things (running tests, managing conflicts, documentation, modularization), its most useful purpose is that of automatically fetching dependencies that your project needs and dependencies of those dependencies (transitive dependencies) if any. Dependencies are usually just JAR files that contain re-usable code.
So what does this mean. Suppose you want to use a library such as OpenCSV to generate a CSV file in your application. Non-Maven way: Google search for the library, check if it needs other libraries and if so download them, put them in your project's classpath then build. When you move your project to another PC, copy all the JAR's or it won't work. Maven way: insert something like this in a file named pom.xml:
<dependency>
<groupId>net.sf.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>2.3</version>
</dependency>
Done. Maven will do the rest for you when you build (download to local cache if not already existing, fetch dependencies, javadoc etc). Even if you were to copy your project to another PC without the JAR's, delete the JAR's etc, if Maven is present it will re-download them automatically when you build.
For more: Link

Related

How to publish a regular, non-Android Java library so that it becomes available for inclusion in Java projects via Maven & Gradle build scripts?

I recently authored a 3rd party library for Java. Currently, I'm distributing the library via Github and a website I own where I make it possible to download the JAR file. I want to make it so developers can use Gradle and Maven (and possibly other build automation tools) to easily include my 3rd party library in their projects.
I'm new to Maven, Gradle, Bintray, JCenter, MavenCentral, Ivy, etc. However, I do have experience with Ant, Java, and Linux.
I've been trying to learn how to publish my 3rd party library using the tools/platforms above, but I've become confused.
Based on what I've read, Gradle, Maven, and Ant are competing technologies. So, why then, in the context of actual use-case scenarios, does Gradle seem to be so intertwined with Maven?
Bintray advertises itself as a software publishing and distribution platform. So, why was there a need to create JCenter as something distinct from the rest of Bintray? What can JCenter do that Bintray can't?
I've created a test package and version on Bintray and I uploaded a JAR file to the version. Is it possible to write a Gradle script that will be able to include that JAR file as a dependency in a Java project? Or does the package need to be "linked" with JCenter?
Basically, can anyone tell me what's going on with all of the above technologies? Don't feel obligated to provide answers to all of the sentences in this post that end in a question mark. Those questions are primarily intended to demonstrate my current level of understanding. A simple overview of how the technologies work together would be great, and if possible, an answer to the question in the title of this post.
I will try answer to all the sentences ending with question marks :)
Based on what I've read, Gradle, Maven, and Ant are competing technologies. So, why then, in the context of actual use-case scenarios, does Gradle seem to be so intertwined with Maven?
Besides being a build tool and a dependency manager (in which Maven compete with Gradle), Maven introduced a standard artifact descriptor (the POM file), a standard project layout (src/main/java etc) and a standard artifact layout (groupId/version/artifactId-version.ext) that due to the popularity of Maven became a standard de-facto in the industry. They aren't particularly bad, so they stuck for now and Gradle works with them as well.
Also, Gradle appeared when Maven already been exceptionally popular. To overtake such a popular technology Gradle had to provide a clean and easy migration path, which means supporting Maven-structured projects, Maven-structured local caches, etc.
Bintray advertises itself as a software publishing and distribution
platform. So, why was there a need to create JCenter as something
distinct from the rest of Bintray? What can JCenter do that Bintray
can't?
JCenter is not "something distinct" from Bintray. JCenter is a repository inside Bintray. This repository is special (we call this type of repository a "Central Repository"), since it is maintained by Bintray team themselves, and include (or link) the biggest collection of Java libraries in the world. For a lot of Java (or Android for that matter) developers, who don't intend to publish their work through Bintray and don't care about other people's personal repositories the only thing of interest on Bintray is JCenter. As such, people refer to JCenter as a thing of its own.
I've created a test package and version on Bintray and I uploaded a
JAR file to the version. Is it possible to write a Gradle script that
will be able to include that JAR file as a dependency in a Java
project?
Absolutely. The "Set Me Up" button opens a window in which you'll find the instructions on how to add your personal repository in Gradle. Once done, the artifacts from your repository will be available for resolution in your Gradle project.
Or does the package need to be "linked" with JCenter?
The benefit of including your package in JCenter is that other developers who are familiar with JCenter as a source for 3rd party dependencies, but not familiar with your repository on Bintray will be able to find and use your library.
I hope it helped.
I am with JFrog, the company behind Bintray and [artifactory], see my profile for details and links.
It is really hard (next to impossible) to give an answer, because you are asking multiple questions (I count 5 question marks), plus you want an explanation of how all of the mentioned technologies play together (or not). This really exceeds the scope and usefulness of stackexchange.
However, if it's maven you could live with, then what you probably want is:
1) deploy your artifact to maven central repo ==> see https://maven.apache.org/guides/mini/guide-central-repository-upload.html
2) deploy to some other well known public maven repo (like sonatype)
3) host your own public maven repo (that can be used by others) and upload there, still keep "advertising" through web and github pages

Distribution of java class library code

I need to put some old java class library code that I have into a repo, from where others can check it out and build it. You know, like any public repo.
But, I'm not sure what the best way to do this is in the java world. In old-fashioned projects, we just used to supply the build scripts and a list of dependencies. You gathered or installed the dependencies separately before running the build scripts.
But these days for many languages, you have package managers and the like that pull from remote locations and your build scripts need to include dependency fetching.
Basically, I'm not familiar with how java libs and programs are packaged.
Should I include the (dependency) libs in the repo? And update them whenever a new version is out?
Does java now have a package manager that will pull in the latest versions of the dependencies?
Do I leave it upto the people checking out to download the libs themselves before they run the build scripts?
I'd prefer it if the solution didn't involve installing a huge package manager. Gradle wants to pull in like 150MB+ of stuff and as far as I am aware, it isn't ubiquitous on java deployments.
Thanks.
Use Maven. I believe these days it's the #1 "package manager" (not a term that's usually used to describe it, but quite apt) by a large margin. It's built into Netbeans, IntelliJ IDEA, and I believe Eclipse.
However, it won't just "pull the latest versions" of your dependencies, since your application may break. Only the versions you specify. Therefore, you should periodically update (and test) your code to reduce incompatibilities when someone tries to use your library in an application which directly or indirectly pulls newer versions of the same libs (and they get into a bit of "dll hell"), or reduce your use of third-party libraries in general.
You should also consider publishing your library in a compiled form to Maven Central so that using your library would be as easy as adding a dependency to the pom.xml. The problem that Maven solves, after all, is not so much making it easy to build your library (since just bundling the dependencies gets you most of the way), but making it easy to use your library.

How to add Maven dependencies to an Android project, in Eclipse, for someone with zero Maven experience?

I've made a few Android apps, but every time I need a library, I'd either download the jar and include it in my /libs folder, or clone the repository and include it as an Android Library. However, many of the more robust libraries recommend using Maven, and considering that more and more people are using it, AND Gradle apparently uses it as well (another system I need to eventually adapt to), I feel like it's time I finally get on board. Unfortunately, most of the tutorials and questions regarding Maven that I've found seem to assume at least a basic working knowledge of the system. What I need is a "Baby's First Maven Tutorial," so to speak. Can anyone help?
For example, the networking library Ion. The Maven dependency block for it is as follows:
<dependency>
<groupId>com.koushikdutta.ion</groupId>
<artifactId>ion</artifactId>
<version>1.2.4</version>
</dependency>
How would one incorporate this library into an existing Android project in Eclipse, via Maven, starting from the very beginning?

Build multiple java projects with dynamic dependencies

I have multiple java projects in a folder. Also there is a second folder with libraries, that might be used as build dependencies from the projects. The projects may also have dependencies to other Projects. What's the best approach to build all projects ?
In other words I want to build the projects without explicit telling their dependencies.I think the biggest problem is the dependecy between the projects.
There are multiple build systems that are available that you may use. Maven has a complete dependency system built into it. Almost all third party open source jars are directly accessible via the World Wide Maven repository system. Basically, you describe the jar you need (groupId, artifactId, and version) and Maven will automatically fetch it for you. Not only that, but Maven also will build your project without having to create a build file. Instead, you have to describe your project in a project object model (a pom.xml file) and Maven will download everything you need, including all compilers, etc.
Almost all new projects use Maven, but Maven has a few downsides:
Since you don't control a build process, it can sometimes feel like poking a prodding a black box to get the build to work the way you want.
Documentation can be scant -- especially if you're moving beyond basic Java compiles.
You usually have to arrange your project in a specific layout. For example, source files should go under src/main/java while JUnit tests are under src/test/java. You don't have to follow the recommended layout, but then you'd have to modify the pom.xml file this way and that to get your build to work. That defeats the whole purpose of the pom.xml in the first place.
If you already have another build system setup (like Ant), you lose everything. There's no easy way to move from Ant to Maven.
The other is called Ant with Ivy. Ivy uses Ant for building, but can access Maven's world wide repository system for third party dependencies. It's a great compromise if you already are heavily invested in Ant. I also find Ant with Ivy to be better documented than Maven (although that's not too difficult). There's an excellent chapter going over the basics of Ivy in Manning Publication's Ant in Action.
With either process, I would recommend that you build a company wide Maven repository using either Nexus or Artifactory. This way, any proprietary third party jars (like Oracle jars) can also be stored in your company wide Maven repository since they won't be in the standard World Wide Maven repository.
By the way, if this is a company wide effort, and you are moving multiple Ant projects into Ivy, I have an Ivy project I use in Github that makes things easier.
Oh, there's a third possibility called Gradle which I know nothing about. I also believe it can use the World Wide Maven repository. It's based on Groovy which is based on Java syntax, and that's about all I can say. Maybe others can fill you in on the details. The Gradle group contends it solves a lot of problems of both Ant/Ivy and Maven.
Whatever tool you use, if you have various projects interdependent, you need to be clear on the independent ones which will be built first before building the dependent projects. You need to have a clear dependency structure for your projects.
You can do this with Apache Ivy. You can lay out the locations for you common libraries, define published artifacts and inter-dependencies in an ivy.xml document in each project, and let a top-level Ant build with the Ivy tasks figure out what the build order should be based on those dependencies.

What is the most elegant solution to managing various Java external libraries?

Perhaps the reason I stalled learning Java until now is because I HATE how Java handles external libraries. I'm stuck keeping them in one place, adding them individually, fixing problems with versioning and every time I move/rename them, and copying and writing the classpath over and over each time I release a Java application.
There has to be an elegant solution to all of this. I keep all of my libraries (regardless of task, platform, or other) in their own little folder inside a "lib" folder in my development folder, kind of like this:
Dev
-lib
+JS-jQuery
+Flex-Degrafa
-Java-Xerces
+Xerces-1.2.3
+More libraries
I can use either Netbeans or Eclipse for Java dev, but none of them provide a very streamlined (and not to mention idiot-proof) way of managing all of these.
A nudge in the right direction or an online article/tutorial on this would be greatly appreciated.
You can either use Ant + Ivy or Maven to manage your library dependencies.
If it is only dependency management you're after and you're happy with the rest of your build process, I would use Ivy, as it can unobtrusively manage your dependencies, leaving your existing build process intact. There is a plugin for Eclipse called IvyIDE that contributes your dependencies via a classpath container.
Maven 2 has a steeper learning curve but provides a much richer set of functionality for building your projects and Eclipse integration through m2eclipse or IAM.
Personally I use Maven as I have a large number of projects to work with and Maven is particularly suited to efficient development across lots of projects.
Have a look at the introductory documentation to see what works for you.
Ivy Tutorial
Maven Getting Started Guide
Netbeans 6.7.1's Maven support is quite good and comes out of the box with the IDE.
The Eclipse addon was frustrating enough that I gave Netbeans another try.
A third choice besides ChssPly76's options is to use Ant with the Maven Ant Tasks. I don't know if I'd call any of these solutions particularly "elegant," but they do spare you the need to manage your own lib/ directory and classpath variables.
If you're working on Linux you can install Java libraries with APT or RPM.
Otherwise, I normally check precompiled JARs into a lib directory in my project's version control repository and make sure the names of the JAR files include full version information. E.g. lib/foo-1.5.6.jar, not lib/foo.jar.
To avoid having to manually set the classpath before running your app, you can set the classpath in the Manifests of the JARs themselves to define the dependencies of each JAR file. The JVM will follow all the dependencies when loading classes.
Maven is often more trouble than it's worth, but the ability to open a maven project directly into IDEs such as IntelliJ is excellent. For example, IntelliJ will download all dependencies and have them available without having to run a build first, or an mvn command and then a project refresh. It also isn't necessary to re-generate the project every time a dependency is added. I work with a number of Eclipse developers who switched to IntelliJ for this alone.
However, one shortfall of Maven is that many libraries (or versions of libraries) are not available on public repositories. Therefore it is often necessary to set up a local repository such as archiva. In ant, it would just be a matter of adding it to the lib directory in the repository.
Maven can also attack when you need to do something that maven doesn't directly support via a plugin. What would normally be a few lines of ant can often turn into a morning's worth of work.
Finally, buildr is an excellent way of using Maven's dependency management and plugins, while also supporting ad-hoc tasks.

Categories

Resources