Showing posts with label maven. Show all posts
Showing posts with label maven. Show all posts

Wednesday, August 5, 2020

How to build a helloworld springboot application in 5 minutes

We assume you have maven installed and know how to run basic command such as "mvn clean package". We also assume you have eclipse with maven plugin installed.

Now our goal is to build a spring application that can print out "hello springboot" in 5 minutes.

Ready?

step 1, Let's build an empty springboot project with spring io. Spring provided an online tool which will create the folder structures, pom file with artifact/group, maven dependencies, plugins, parent pom ready. It will also generate a dummy application.properties, springboot application main class file for us for free. Anyway, who want to write all those boiling plates for the helloworld program?

click generate to create a springboot application


  • go to https://start.spring.io/ fill in the group and artifact, click generate. 
  • once the website generated your spring boot code then downloaded to your local and unzip it.
  • open a shell command window, go to your unzipped directory, issue the following command

springboot>cd Downloads/mydemo
springboot>mvn clean package
springboot>tree

The maven will download all the dependencies specified in the pom.xml and have the project compiled.

step 2. import the project into eclipse. We will run the springboot application, make sure it is start without exceptions. 
import existing maven project

  • click File -> Import.. 
  • under Maven, select Existing Maven Project
  • navigate to the unzipped folder and click open
Step 3. Run the springboot. The entry point of spring boot is nothing but a main method.

package my.example.com.mydemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MydemoApplication {

public static void main(String[] args) {
SpringApplication.run(MydemoApplication.class, args);
}

}

We right click the file, then select Run As Java Application.
We just ran the famous springboot application. Nothing special, the output should looks like the following.


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.0.RELEASE)

2020-06-02 14:48:47.315  INFO 5407 --- [           main] my.example.com.mydemo.MydemoApplication  : Starting MydemoApplication on Meifangs-MBP.home with PID 5407 (/Users/homenetwork/Downloads/mydemo/target/classes started by homenetwork in /Users/homenetwork/Downloads/mydemo)
2020-06-02 14:48:47.319  INFO 5407 --- [           main] my.example.com.mydemo.MydemoApplication  : No active profile set, falling back to default profiles: default
2020-06-02 14:48:47.945  INFO 5407 --- [           main] my.example.com.mydemo.MydemoApplication  : Started MydemoApplication in 1.091 seconds (JVM running for 2.206)

Step 4. print hello springboot.

The default main method did many things though appears doing nothing. The spring framework is started, it looking for the @SpringBootApplication annotation then register this class as the entry point.  Next, we will add a springboot scheduler, so that it keep printing "hello springboot" every 10 seconds.

  • modify the MydemoApplication.java, at the class level add the @EnalbeScheduling annotation, then add a method with annotation @scheduled(fixedRate=5000)
package my.example.com.mydemo;

import java.time.LocalDateTime;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

@SpringBootApplication
@EnableScheduling
public class MydemoApplication {

public static void main(String[] args) {
SpringApplication.run(MydemoApplication.class, args);
}
@Scheduled(fixedRate = 5000)
void updateStatus() {
    System.out.println("hello springboot at " + LocalDateTime.now());
}
}

Run the program again. This time, the spring boot will print hello springboot every 5 seconds until you stop it. The annotation @EnableScheduling tells the spring framework that this springboot application will invoke springboot schedulers to run periodic tasks. With this information, the spring framework (imaging spring framework as a magician and your annotations are spells) then searches methods with annotation @scheduled, the annotated method will be the task run periodically. The @scheduled annotation may also have information such as period, delay etc. The spring framework will read in those information, and schedule the task when the spring boot application start.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.0.RELEASE)

2020-06-02 15:00:10.434  INFO 5424 --- [           main] my.example.com.mydemo.MydemoApplication  : Starting MydemoApplication on Meifangs-MBP.home with PID 5424 (/Users/homenetwork/Downloads/mydemo/target/classes started by homenetwork in /Users/homenetwork/Downloads/mydemo)
2020-06-02 15:00:10.437  INFO 5424 --- [           main] my.example.com.mydemo.MydemoApplication  : No active profile set, falling back to default profiles: default
2020-06-02 15:00:11.194  INFO 5424 --- [           main] o.s.s.c.ThreadPoolTaskScheduler          : Initializing ExecutorService 'taskScheduler'
2020-06-02 15:00:11.236  INFO 5424 --- [           main] my.example.com.mydemo.MydemoApplication  : Started MydemoApplication in 1.284 seconds (JVM running for 2.292)
hello springboot at 2020-06-02T15:00:11.239
hello springboot at 2020-06-02T15:00:16.213
hello springboot at 2020-06-02T15:00:21.213

Step 5. add a little bit seasonings to the hello springboot.

We can make the helloworld program a little bit tasty by making it configurable. For example, we can set the time interval as a variable, then put it in a configuration file, so that we don't have to change the java class if we decided to use a shorter or longer interval later.
application.properties

  • set the properties file. Open application add content 
statusLoader.delay=PT10S
  • modify the main class.
package my.example.com.mydemo;

import java.time.LocalDateTime;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

@SpringBootApplication
@EnableScheduling
public class MydemoApplication {

public static void main(String[] args) {
SpringApplication.run(MydemoApplication.class, args);
}
@Scheduled(initialDelay=3000L, fixedDelayString="${statusLoader.delay}")
void updateStatus() {
    System.out.println("hello springboot at " + LocalDateTime.now());
}
}
run the program again
This time, the time interval changes to 10 seconds.
You can change it to longer and shorter time interval and observe the changes. 

The spring framework by default load any properties defined in the application.properties file. When a variable is referenced as a meta data in an annotation, "${statusLoader.delay}, spring framework will check if any properties in its context matches, then replace the variable with the value string. Now the spell became concrete @Scheduled(initialDelay=3000L, fixedDelayString=PT10S), the spring framework can create a scheduler thread under the sleeve, run every 10 seconds with 3 seconds initial delay. The scheduled threadpool has similar effect as the following code:

    Executors.newScheduledThreadPool(1).scheduleAtFixedRate(() 
            -> System.out.println("hello springboot at" + LocalDateTime.now()), 
            3, 10, TimeUnit.SECONDS);

Hope this helps.


Friday, May 29, 2020

How to set up maven in mac os x

first download apache maven, the downloads url is: http://maven.apache.org/download.html

unpack it to a folder, say /Users/yourid/Downloads/apache-maven-3.3.3

modify your ~/.bashrc, make sure the following lines are there

export M2_HOME=/Users/yourid/Downloads/apache-maven-3.3.3
export PATH=$PATH:$PATH:$M2_HOME/bin

now you can use maven in command line and eclipse or intellij etc.

advanced maven command line

mvn dependency:resolve install
mvn versions:set -DnewVersion=1.2.2
mvn clean install -U
mvn dependency:tree

Eclipse common maven actions

right click a project,
preferences --> maven --> update project.
preferences --> Maven: select Download Artifact sources
preferences --> Maven --> installation: set the maven location
right click a project, run as --> maven install

Thursday, February 7, 2019

How to consuming a soap endpoint in java

A soap end point looks something like
http://xyzcode.xyz/quote
usually the wsdl file can be download from
http://xyzcode.xyz/quote?wsdl

The wsdl file will give the instruction about how to consume the soap web service, that is all you needed to know in order to talk to soap api besides the user/pass for authentication.

Start with a wsdl file such as quote.wsdl, you can import the file into third-party gui tools such as soapUI, then you fill up all the fields for the request in xml format, and press send then wait, the soapUI will send your request to the remote endpoint with soap protocol, then get the response, then print the output in xml format.

Instead of manually filling the request fields in SoapUI GUI, you can have a java program to automatically fill all the needed fields, construct the request object, serialize it, have a SAAJ client send the request down to the wire with soap protocol, then wait for the SAAJ client to get the soap response back, then deserialize the response into response object.

The following tools and packages are what you need to make it happen.

1. apache wsdl2java.
Once you downloaded the tool from apache site, you can issue the following command to convert the wsdl file into corresponding java files.
The command is:
wsdl2java quote.wsdl

You most likely end up with 2 folder generated: com and org, within which, your wsdl generated java files reside.

An important thing to note is: the tool generated many ObjectFactory.java files for serializer and deserializer to consume. You can find the location of those OjectFactory.java by the following command:

find . -name ObjectFactory.java

the output could be something like:

./com/yourinventit/processing/android/serial/ObjectFactory.java
./com/yourinventit/processing/android/ObjectFactory.java
./org/helloexample/ObjectFactory.java

2. SAAJ client
The SOAP with Attachments API for Java or SAAJ provides a standard way to send XML documents over the Internet from the Java platform.

The maven saaj dependency is:
<dependency>
    <groupId>com.sun.xml.messaging.saaj</groupId>
    <artifactId>saaj-impl</artifactId>
    <version>1.5</version>
</dependency>

With saaj you can create soap calls like the following. In order to request, we need to create the Request message. Follow the same way we used to fill the request form in soapUI GUI, here we need to fill many fields in the request SOAPMessage object as well. We fill these fields with the help of wsdl generated classes.

SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection connection = soapConnectionFactory.createConnection();
URL endpoint = new URL("http://xyzcode.xyz/quote");
MyPayload payload = business.getRequest();  //pass in from call param
SOAPMessage  message = funcCreateRequest(payload);  //use wsdl generated classes
SOAPMessage response = connection.call(message, endpoint);
connection.close();

3. jaxb
We said that we fill soap request fields with the help of wsdl generated classes. In fact, there are java library to help serialize and deserialize your soap request and response. The tool for that is jaxb.
You can include jaxb using maven.

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.2.12</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.2.11</version>
</dependency>

Once you have jaxb, you need to tell JAXBContext where to find the ObjectFactory.java files in order to serialize and deserialize soap objects generated by the wsdl file.
With the above example, your initialization will looks like:

JAXBContext jc = JAXBContext.newInstance("com.yourinventit.processing.android.serial:com.yourinventit.processing.android:org.helloexample:org.helloexample");

Once you have the JAXB initialized, you can convert between object and xml string.
For request

MyPayload payload = business.getRequest();  //pass in from call param
Marshaller m = jc.createMarshaller();
StringWriter w = new StringWriter();
xsw = XMLOutputFactory.newInstance().createXMLStreamWriter(w);
m.marshal(payload, xsw);  //consume objects specified in ObjectFactory.java
String requestString = w.getBuffer().toString();
SOAPMessage soapMessage = funcBuildSoapRequest(requestString);

For response
Node payload = soapMessage.getSOAPBody().getFirstChild();
String responseString  = funcConvertPayloadToString(payload);
Unmarshaller u = jc.createUnMarshaller();
xsr = XMLInputFactory.newInstance().createXMLStreamReader(new StringReader(responseString));
Object o = unmarshaller.unmarshal(xsr);  //consume objects specified in ObjectFactory

The "Object o" can be cast to one of the wsdl object, then you can pass the object around in your program.



Wednesday, January 30, 2019

7 Software release tools you should know

DevOps
DevOps


You can do your release management as simple as command-line: mvn release:prepare;mvn release:perform.

However, there are lots of tools that make your release great and pleasant.
1. jira
Your project manager and scrum master can manage the release process with jira. A jira can integrate with bitbucket, slack, confluence etc. You can branch out github code base or create pull request in jira. Whenever you checked in code or created pull request, the jira will show updates; your co-worker can even get email when their name get mentioned or pull request is assigned to them. You can created all sorts of jiras: story, task, deployment, bug, feature, incident, etc. These jiras can have all sorts of relationships: subtask, related to, block, epics, etc. Isn't that pleasant?

2. bitbucket, github
You can do all git action with command line, however git management tools such as bitbucket makes your git usage much more efficient. In bitbucket, you can do basic operations such as create repository, create branches, create pull request, code review, merge, etc. It can do more than that. When bitbucket is integrated with bamboo or jenkins, your code check-in will trigger auto-build, and the build result can be a factor in the merge criteria. Besides, your merge will trigger auto version update, isn't it magical? Whenever you want, you can get lots of information by searching code base, lookup pull requests, filter on pull requests, compare tagged versions, and lots more.

3. sonatype nexus
Maven central repository allow your maven project to find dependencies. However, if you want to manage your own private jar collections, your may need a repository manager server like sonatype nexus. It allows you to proxy, collect, and manage your dependencies. With a few lines about the repo server url and credential added into ~/.m2/settings.xml file, the developers can publish to your sonatype nexus server hosted repos, this will also allow your mvn to use your repo as a mirror of central.

4. IC tools
Tools such teamcity, jenkins, electric cloud, bamboo act as the continuous integration build server. These build servers tie automated builds, tests, and releases together in a single workflow. For example, when bamboo is integrated with bitbucket, code check in will trigger bamboo builds. Some builds create snapshot artifacts, others create released artifacts. With the gui, you can create new build project, set up the trigger criteria, specify the git repo, specify the test/release command such as
mvn release:prepare;mvn release:perform;
You can even setup the quality gates by adding Nexus IQ and SonarQube etc. as release gate tasks.

5. Nexus IQ
You don't want to have code vulnerability to be in production, so you can setup Nexus IQ tool to scan and find bad codes. The Nexus IQ setup gui allows you to customize policy, so you can define which components are acceptable, and which are not.

6. SonarQube
Besides code coverage, SonarQube can do more such as finding smelly code or bad style, so your code is not only reliable but also smells good.

7. Automatic deployment tools
After IC tools finished test and release, they will create artifacts that need to be deployed on various servers on your DEV, QA, PILOT or PROD environment. You can use scp commands to copy the artifact such as jar, war, zip, tar.gz files on the target server's web-service (such as tomcat/jboss) directory. However, you don't have to do this kind of routine manually. Your IC tool can trigger an automatic deployment job as one of the release task. For example, automatic deployment tools such as RunDeck, Puppet, bladelogic etc. can execute user defined deployment jobs on server nodes. These nodes are your unix servers located on different environment. The artifacts are push to those nodes automatically at the end of the IC process.




Thursday, January 24, 2019

maven trouble-shooting checklist

In theory, in order to use maven to build a project, all you need to do is to download maven, then update ~/.bashrc to have maven bin in $PATH.

export PATH=/Users/youruser/Downloads/apache-maven-3.2.5/bin/:$PATH

However, in reality, sometimes your maven gets stuck when downloading dependencies. Don't blame yourself for fat fingers, for big projects, the maven build process different every single time! First of all, your dependency could have snapshot versions, which might get updated on the repo 5 minutes ago, so when maven downloaded the latest one, trouble is introduced. Even though your direct dependency have no snapshot version. Your indirect dependency could have snapshot version dependency, downloading them also brings new jars which brings trouble into your build process. Besides, your OS/network admin could applied rules on your account, so that some of your remote repos can no longer be reached. Your build will still go on because your cached jar in local repo, however the cached version is now differ from the latest version, so your build process will differ from your coworkers' build process. Even though nothing happens in the environment, your download could be erroneous during file transfer due to network package loss, memory buffer, stale file stub etc.

Here are a trouble-shooting checklist.

1. find which maven is used.

which mvn

This command also tells you the maven home location.

There are two locations where a settings.xml file may live:
The Maven install: ${maven.home}/conf/settings.xml
A user’s install: ~/.m2/settings.xml
The user's install takes precedence than the other.

check both settings.xml file to make sure what properties are override. Without override, you default maven repo should locate inside ~/.m2/repository

2.  find if the complained jar file is in your local and remote repo or not.
The maven build will check local cache first, then go to download the remote repo for snapshot versions and won't download the release versions.
If the jar file is in the local repository ~/.m2/repository. It could be corrupted during download. You can use
mvn clean -U package
to force maven to re-download the existing local repository files from remote repository.
To achieve the same goal, you can also delete that dependency folder, or even the entire ~/.m2/repository folder, so that maven can not find the jar in local cache and have to trip to the remote repository to re-download everything.

Notice often times, the maven is complain about a jar and its depended jar file chains -- check each one of them, not just the first one in the complained list!

If you are helping others to trouble shoot build issue and the complained jar files are in your local repo but not in the remote repo. Chances are it just builds for you but won't build for others. Because someone has deleted the needed jar files in the remote repository, leaving a bug in the unaware victim code base.

3. restart you computer if possible. It will fix weird issues related to memory and network policy etc. For example network policy changes when you work from home with vpn then work in office.

4. check eclipse maven settings.
in eclipse -> preferences -> maven -> user settings, make sure you didn't override any default settings, so that you are using the default local repository. If you don't want to rely on default, literally specify the default location so that you are sure.

right click the project, then "maven", then "update project..", you can check the force update check box to have eclipse do the equivalent of
mvn clean -U package

5. restart eclipse, eclipse could run into weird issue internally.

6. ask if other people has the same build issue, then ask them to send you the ~/.bashrc, ~/.bash_profile, ~/.m2/settings.xml, and the /path-to-maven-home/conf/settings.xml. Also ask for the result of ls -lrt ~/.m2/repository/path/to/complained/jar

7. if you are using git or svn, find out who added the dependency that causes the trouble, have a conversation about it.

Monday, September 24, 2018

7 tools providing visibility for maven dependency tree

With maven pom.xml, you can have maven manage your project's dependency automatically. Whenever your project's code needs classes in a jar file, you can specify the dependency in your pom.xml, and give it a scope to specify whether this jars is needed for compile time, run time or test time. As long as the jars exist in maven repository, they will be downloaded into your local repository, which by default under ~/.m2/repository. Your project will include a set of jars which you specify in your pom.xml, they maps to the jar folders in ~/.m2/repository, and maven will include them in classpath. Those depended jars also has dependency specified in their own pom.xml. Maven goes one step further to download all the jars in the dependency chain, and have a set of rules to figure out which jar version takes precedence when it is declared in multiple places -- for example, when a jar version is declared in both parent pom and child pom, child pom takes precedence.

Enough theory about maven, here are 7 tools help you get visibility of maven dependency tree.
The example maven project used below can be checkout with "git clone https://github.com/GoogleCloudPlatform/appengine-gcs-client.git"

1. locate the dependency jar file. The groupId + artifactId + version in your pom.xml file is mapping to the corresponding directory. for example <groupId>org.codehaus.mojo</groupId> + <artifactId>versions-maven-plugin</artifactId> + <version>2.2</version> in the following example maps to ~/.m2/repository/org/codehaus/mojo/versions-maven-plugin/2.2/



>grep groupId pom.xml -A 2
    <groupId>com.google.appengine.tools</groupId>
    <artifactId>appengine-gcs-client-example</artifactId>

--
            <groupId>com.google.appengine</groupId>
            <artifactId>appengine-api-1.0-sdk</artifactId>
            <version>${appengine.version}</version>
--
            <groupId>com.google.appengine.tools</groupId>
            <artifactId>appengine-gcs-client</artifactId>
            <version>0.6</version>
--
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
--
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
--
            <groupId>com.google.appengine</groupId>
            <artifactId>appengine-api-stubs</artifactId>
            <version>${appengine.version}</version>
--
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>versions-maven-plugin</artifactId>
                <version>2.2</version>
--
                <groupId>org.apache.maven.plugins</groupId>
                <version>3.5.1</version>
                <artifactId>maven-compiler-plugin</artifactId>
--
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.6</version>
--
                <groupId>com.google.appengine</groupId>
                <artifactId>appengine-maven-plugin</artifactId>
                <version>${appengine.version}</version>
--
              <groupId>com.google.appengine</groupId>
              <artifactId>gcloud-maven-plugin</artifactId>
              <version>${gcloud.plugin.version}</version>
>ls ~/.m2/repository/org/codehaus/mojo/versions-maven-plugin/2.2/
_remote.repositories versions-maven-plugin-2.2.jar versions-maven-plugin-2.2.pom
m2e-lastUpdated.properties versions-maven-plugin-2.2.jar.sha1 versions-maven-plugin-2.2.pom.sha1
>      

In eclipse, you can hold command key and click a dependency in your pom.xml to step into the dependency jar's pom.xml file which located in a folder under ~/.m2/repository.

2. display dependency tree. The command "mvn dependency:tree" will display the dependency hierarchy in a tree structure. For example, com.google.oauth-client:google-oauth-client:jar:1.21.0:compile is an indirect dependency introduced by com.google.appengine.tools:appengine-gcs-client:jar:0.6:compile in your pom.xml.


>mvn dependency:tree
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building appengine-gcs-client-example 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ appengine-gcs-client-example ---
[INFO] com.google.appengine.tools:appengine-gcs-client-example:war:1.0-SNAPSHOT
[INFO] +- com.google.appengine:appengine-api-1.0-sdk:jar:1.9.36:compile
[INFO] +- com.google.appengine.tools:appengine-gcs-client:jar:0.6:compile
[INFO] |  +- com.google.guava:guava:jar:19.0-rc1:compile
[INFO] |  +- joda-time:joda-time:jar:2.3:compile
[INFO] |  +- com.google.apis:google-api-services-storage:jar:v1-rev68-1.21.0:compile
[INFO] |  |  \- com.google.api-client:google-api-client:jar:1.21.0:compile
[INFO] |  |     \- com.google.oauth-client:google-oauth-client:jar:1.21.0:compile
[INFO] |  +- com.google.api-client:google-api-client-appengine:jar:1.25.0:compile (version selected from constraint [1.19,2.0))
[INFO] |  |  +- com.google.oauth-client:google-oauth-client-appengine:jar:1.25.0:compile
[INFO] |  |  |  \- com.google.oauth-client:google-oauth-client-servlet:jar:1.25.0:compile
[INFO] |  |  |     \- com.google.http-client:google-http-client-jdo:jar:1.25.0:compile
[INFO] |  |  +- com.google.api-client:google-api-client-servlet:jar:1.25.0:compile
[INFO] |  |  |  \- javax.jdo:jdo2-api:jar:2.3-eb:compile
[INFO] |  |  |     \- javax.transaction:transaction-api:jar:1.1:compile
[INFO] |  |  \- com.google.http-client:google-http-client-appengine:jar:1.25.0:compile
[INFO] |  +- com.google.http-client:google-http-client:jar:1.25.0:compile (version selected from constraint [1.19.0,2.0))
[INFO] |  |  +- com.google.code.findbugs:jsr305:jar:3.0.2:compile
[INFO] |  |  +- org.apache.httpcomponents:httpclient:jar:4.5.5:compile
[INFO] |  |  |  +- org.apache.httpcomponents:httpcore:jar:4.4.9:compile
[INFO] |  |  |  +- commons-logging:commons-logging:jar:1.2:compile
[INFO] |  |  |  \- commons-codec:commons-codec:jar:1.10:compile
[INFO] |  |  \- com.google.j2objc:j2objc-annotations:jar:1.1:compile
[INFO] |  \- com.google.http-client:google-http-client-jackson2:jar:1.25.0:compile (version selected from constraint [1.19,2.0))
[INFO] |     \- com.fasterxml.jackson.core:jackson-core:jar:2.9.6:compile
[INFO] +- javax.servlet:servlet-api:jar:2.5:provided
[INFO] +- jstl:jstl:jar:1.2:compile
[INFO] \- com.google.appengine:appengine-api-stubs:jar:1.9.36:test
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.037 s
[INFO] Finished at: 2018-09-24T21:19:12-04:00
[INFO] Final Memory: 17M/226M
[INFO] ------------------------------------------------------------------------
>

In eclipse, it is equivalent to the "Effective POM" tab's output.


The eclipse even goes one step further to list all the jar dependency chains in "Dependency Hierarchy" tab. Those needed but overruled jar versions are marked as "omitted for conflict".


3. you can force maven to download the source code for your jar files if they are available in maven remote repository. "mvn dependency:sources".

You can do the same in eclipse by right click a project -> Maven -> Download Sources


4. Sometimes you get a dependent jar that almost meets your requirement except some small dissatisfaction. You can check out the source code from svn, git, etc, modify the code, then issue "mvn install". This command will publish an artifact into your local repository. Other project want to use them can reference it with a dependency entry in pom.xml. For example, run "mvn clean install" for the example will create an artifact under .m2/repository/com/google/appengine/tools/appengine-gcs-client-example/1.0-SNAPSHOT/appengine-gcs-client-example-1.0-SNAPSHOT.pom, you can reference this artifact with

      <dependency>
            <groupId>com.google.appengine.tools</groupId>
            <artifactId>appengine-gcs-client-example</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>

        </dependency>

in other projects' pom.xml.

You can do the same in eclipse, by right clicking the project, then selecting Run as, then clicking Maven Install. Notice due to eclipse bug,  org.codehaus.mojo:versions-maven-plugin can not be executed, I comment it out to get the maven install running. It won't hurt main functionality, this plugin as the name says, is a nice to have step during compile.


5. You can build maven project with command line, then import the built project into eclipse or have eclipse synchronize with the update. To import an maven project in eclipse, you click File -> Import -> expand maven folder, select "Existing Maven Projects" -> click Next -> browse to the pom.xml you wan to import. To update maven project in eclipse, whenever you built maven project with command line, you right click the project, select maven then click "update project...". 

6. You can inspect exactly what jars your eclipse project has in the classpath, these jars are introduced by maven plugin. 



7. Finally, you resolved the dependency issue by specifying a particular dependent jar version to override the maven chosen version or adding a list of <exclusions><exclusion></exclusion>...</exclusions>  under some <dependency></dependency> to force maven to reconsider the version. Problem now solved, you can update the project versions to a higher one to mark this fix. You can change multiple pom.xml file versions with command "mvn versions:set -DnewVersion=1.3.x-SNAPSHOT. The versions:set goal will automatically climb up local directories to find the aggregation root. It will automatically update explicitly referenced dependencies.


MarketAxess

MarketAxess: The Leader in e-Trading for Global Fixed Income MarketAxess Holdings Inc. (MarketAxess) is an international financial technol...