How to get maven dependency tree programmatically - maven

want to print maven dependency tree (all the dependencies including transitive dependencies) programmatically by just reading pom.xml file without connecting to remote repository.

Not really possible, sorry. Also, have you checked the answer and comments here? How can you display the Maven dependency tree for the *plugins* in your project?

I can recommend to take a look at the maven resolver project which has some example code which might be sufficient as a starting point:
https://github.com/apache/maven-resolver/tree/master/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples

You can do this by using ProcessBuilder to retrieve the result of maven's dependency:tree command.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public static void main(String[] args) {
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("cmd.exe", "/c", "mvn -f \"C:\\myprojectpath\"", "dependency:tree");
try {
Process process = processBuilder.start();
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("\nExited with error code : " + exitCode);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Read more here.

Related

spring mvc how to get build success or failure state, after build has finished and created .war file

I just want to execute a local "cmd" file right after finished and success to build .war file.
on spring boot Web Application i have tested successfully on this code.
//MainApplication.java
#EventListener(ApplicationReadyEvent.class)
public void doSomethingAfterStartup() {
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("cmd.exe", "/c", "ls D:\\workspace\\web\\target\\");
processBuilder.command("D:\\workspace\\web\\target\\example.cmd");
try {
Process process = processBuilder.start();
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("\nExited with error code : " + exitCode);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
But how to get mvc build state, in order to execute a .cmd file right after build has finished and created .war file on /target directory successfully.
this code doesn't run on mvc build.
Thank you!

How to run grunt commands in git-bash using java class program and display in console

I need to open to run grunt task runner and Git commands from this class file, but am not sure how to pass the commands.I tried all those specified on the web but they only workout for cmd.Also i can't understand all those /k and /c those tags.where can i find all those refereances.
1.Change Directory
2.run grunt task -(grunt , grunt watch...)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Cmdtesttwo {
public static void main(String[] args) throws IOException {
ProcessBuilder builder = new ProcessBuilder("C:\\Program Files\\Git\\git-
bash.exe"," grunt");
builder.redirectErrorStream(true);
Process p = builder.start();
BufferedReader r = new BufferedReader(new
InputStreamReader(p.getInputStream()));
String line;
while (true) {
line = r.readLine();
if (line == null) { break; }
System.out.println(line);
}
}
}
You can simply do it like below, here your command/program output will be printed in a output.txt file. Do not forget to create log folder:-
String[] command ={"C:\\Program Files\\Git\\git-bash.exe", "grunt"};
ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectOutput(new File("C:\\log\\output.txt"));
try {
Process p = pb.start();
p.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}catch (Exception e1) {
e1.printStackTrace();
}

Launch browser automatically after spring-boot webapp is ready

How do I launch a browser automatically after starting the spring boot application.Is there any listener method callback to check if the webapp has been deployed and is ready to serve the requests,so that when the browser is loaded , the user sees the index page and can start interacting with the webapp?
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
// launch browser on localhost
}
Below code worked for me:
#EventListener({ApplicationReadyEvent.class})
void applicationReadyEvent() {
System.out.println("Application started ... launching browser now");
browse("www.google.com");
}
public static void browse(String url) {
if(Desktop.isDesktopSupported()){
Desktop desktop = Desktop.getDesktop();
try {
desktop.browse(new URI(url));
} catch (IOException | URISyntaxException e) {
e.printStackTrace();
}
}else{
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("rundll32 url.dll,FileProtocolHandler " + url);
} catch (IOException e) {
e.printStackTrace();
}
}
}
#SpringBootApplication
#ComponentScan(basePackageClasses = com.io.controller.HelloController.class)
public class HectorApplication {
public static void main(String[] args) throws IOException {
SpringApplication.run(HectorApplication.class, args);
openHomePage();
}
private static void openHomePage() throws IOException {
Runtime rt = Runtime.getRuntime();
rt.exec("rundll32 url.dll,FileProtocolHandler " + "http://localhost:8080");
}
}
You could do it by some java code. I am not sure if spring boot has something out of the box.
import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class Browser {
public static void main(String[] args) {
String url = "http://www.google.com";
if(Desktop.isDesktopSupported()){
Desktop desktop = Desktop.getDesktop();
try {
desktop.browse(new URI(url));
} catch (IOException | URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("xdg-open " + url);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
I've recently been attempting to get this working myself, I know it's been a while since this question was asked but my working (and very basic/simple) solution is shown below. This is a starting point for anyone wanting to get this working, refactor as required in your app!
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.awt.*;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
openHomePage();
}
private static void openHomePage() {
try {
URI homepage = new URI("http://localhost:8080/");
Desktop.getDesktop().browse(homepage);
} catch (URISyntaxException | IOException e) {
e.printStackTrace();
}
}
}
If you package the application as a WAR file, configure an application server, like Tomcat, and restart the configured application server through your IDE, IDEs can automatically open a browser-tab.
If you want to package your application as a JAR file, your IDE will not be able to open a web browser, so you have to open a web browser and type the desired link(localhost:8080). But in the developing phase, taking these boring steps might be very tedious.
It is possible to open a browser with Java programming language after the spring-boot application gets ready. You can use the third-party library like Selenium or use the following code snippet.
The code snippet to open a browser
#EventListener({ApplicationReadyEvent.class})
private void applicationReadyEvent()
{
if (Desktop.isDesktopSupported())
{
Desktop desktop = Desktop.getDesktop();
try
{
desktop.browse(new URI(url));
} catch (IOException | URISyntaxException e)
{
e.printStackTrace();
}
} else
{
Runtime runtime = Runtime.getRuntime();
String[] command;
String operatingSystemName = System.getProperty("os.name").toLowerCase();
if (operatingSystemName.indexOf("nix") >= 0 || operatingSystemName.indexOf("nux") >= 0)
{
String[] browsers = {"opera", "google-chrome", "epiphany", "firefox", "mozilla", "konqueror", "netscape", "links", "lynx"};
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < browsers.length; i++)
{
if (i == 0) stringBuffer.append(String.format("%s \"%s\"", browsers[i], url));
else stringBuffer.append(String.format(" || %s \"%s\"", browsers[i], url));
}
command = new String[]{"sh", "-c", stringBuffer.toString()};
} else if (operatingSystemName.indexOf("win") >= 0)
{
command = new String[]{"rundll32 url.dll,FileProtocolHandler " + url};
} else if (operatingSystemName.indexOf("mac") >= 0)
{
command = new String[]{"open " + url};
} else
{
System.out.println("an unknown operating system!!");
return;
}
try
{
if (command.length > 1) runtime.exec(command); // linux
else runtime.exec(command[0]); // windows or mac
} catch (IOException e)
{
e.printStackTrace();
}
}
}
Using Selenium to open a browser
To use the selenium library add the following dependency to your pom.xml file.
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
Then in your main class, add the following code snippet.
#EventListener({ApplicationReadyEvent.class})
private void applicationReadyEvent()
{
String url = "http://localhost:8080";
// pointing to the download driver
System.setProperty("webdriver.chrome.driver", "Downloaded-PATH/chromedriver");
ChromeDriver chromeDriver = new ChromeDriver();
chromeDriver.get(url);
}
Notice: It is possible to use most of the popular browsers like FirefoxDriver, OperaDriver, EdgeDriver, but it is necessary to download browsers' drivers beforehand.
Runtime rt = Runtime.getRuntime();
try {
rt.exec("cmd /c start chrome.exe https://localhost:8080");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
The code above worked for me. Change chrome.exe to the browser of your choice and Url to to your choice.
Note: You must include the scheme - http or https, and the browser you choose must me installed, else your app will run without opening the browser automatically.
Works only for windows though.

How can I get maven to just print pom coordinates?

I would like maven to parse a pom file for me and just print out the coordinates of the generated artifact(s). Maven is obviously parsing this info, I just want to know how to get it printed and then have maven stop. I want to use this in some shell scripting, and parsing the pom seems onerous to do in bash - especially with all the inheritance implications and dependency coordinates listed throughout. I don't want any building to occur since I may only have the POM, not the source files.
The best way I've found so far is to parse the output of this:
mvn -N dependency:tree
This seems a bit heavy-weight since it parses ALL dependencies. Is there a better way to do this?
You can create a small java programm which exactly does this like the following:
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
public class PomRead {
public String getPomVersion(Model model) {
String result = model.getVersion();
if (result == null) {
throw new IllegalArgumentException("The artifact does not define a version.");
}
return result;
}
public Model readModel(InputStream is) throws IOException, XmlPullParserException {
MavenXpp3Reader model = new MavenXpp3Reader();
Model read = model.read(is);
return read;
}
public Model readModel(File file) throws IOException, XmlPullParserException {
FileInputStream fis = new FileInputStream(file);
return readModel(fis);
}
public String getVersionFromPom(File pomFile) throws IOException, XmlPullParserException {
Model model = readModel(pomFile);
return getPomVersion(model);
}
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("Invalid number of arguments.");
System.err.println("");
System.err.println("usage: pom.xml");
return;
}
String pom = args[0];
File pomFile = new File(pom);
if (!pomFile.exists() || !pomFile.isFile() || !pomFile.canRead()) {
System.err.println("File " + pomFile + " can not be accessed or does not exist.");
return;
}
PomRead pomRead = new PomRead();
try {
String version = pomRead.getVersionFromPom(pomFile);
System.out.println(version);
} catch (IllegalArgumentException e) {
System.err.println(e.getMessage());
} catch (IOException e) {
System.err.println(e.getMessage());
} catch (XmlPullParserException e) {
System.err.println(e.getMessage());
}
}
}
You need of course the following pom.xml for that small program where a single dependency is important:
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-model</artifactId>
<version>3.0.5</version>
</dependency>
May be it should be added such a goal to one of the numerous maven plugins to support such a thing. The above prints out the version only but can simply be enhanced to print also groupId and artifactId.

HTMLUnit webClient.getPage(locationToPing) is blocked when the jar is invoked from Runtime.exec()

I am writing an application that needs to load a jar periodically. The Jar fetches the content of a website making use of HTMLUnit.When this jar is run from commond prompt it runs as expected. But when I run it using java code by making use of Runtime, it blocks at the place , page= webClient.getPage(locationToPing);
and doesnt proceed furhter.
The Jar contains only one java class as given below,
package tempproj2;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Fetcher {
String locationToPing;
volatile WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
HtmlPage page ;
public static final long SLEEP_TIME_IF_CONNECTION_WAS_REFUSED=10000; //SECS
public long connectionRefusedTime=0;
private static Fetcher theOnlyInstanceOfThisClass=new Fetcher();
public static Fetcher getInstance(){
return theOnlyInstanceOfThisClass;
}
private Fetcher(){
init();
fetchUsingGet();
}
private void init(){
locationToPing="http://www.mail.yahoo.com";
}
private void fetchUsingGet(){
try {
System.out.println("-----------Start 1 --------------") ;
webClient.setUseInsecureSSL(true);
webClient.setThrowExceptionOnScriptError(false);
System.out.println("-----------Start 2 --------------") ;
webClient.setJavaScriptEnabled(true);
System.out.println("-----------Start 3 --------------") ;
webClient.setTimeout(5000); //30 secs - its int n not long be careful abt it.
System.out.println("-----------Start 4 --------------locationToPing="+locationToPing) ;
page= webClient.getPage(locationToPing);
System.out.println("-----------Start 5 --------------"+page.asXml()) ;
} catch (Exception ex) {
System.out.println("-----------IC Fetecher Error here --------------"+ex.getMessage()) ;
connectionRefusedTime=System.currentTimeMillis();
ex.printStackTrace();
}
}
private void reload(){
if(page==null){
fetchUsingGet();
return;
}
try {
page=(HtmlPage)page.refresh();
} catch (java.net.SocketTimeoutException ex) {
fetchUsingGet();
ex.printStackTrace();
}catch(IOException ex){
ex.printStackTrace();
}
}
public static void main(String ar[]){
Fetcher fetcher=new Fetcher();
while(true){
try {
Thread.sleep(4*1000);
} catch (InterruptedException ex) {
Logger.getLogger(Fetcher.class.getName()).log(Level.SEVERE, null, ex);
}
fetcher.reload();
}
}
}
Given below are the different ways I tried to run the above code
Run the class as it is - Runs fine.
Make a Jar of the above class and run from the command prompt using java -jar , command - Runs fine.
Make a Jar of above class and run it from another java class using the following code,
try {
String execCmd="java -jar "+downloadApplicationJarLocation.getAbsolutePath();
Process pr=Runtime.getRuntime().exec(execCmd) ;
InputStreamReader is = new InputStreamReader(pr.getInputStream());
BufferedReader br = new BufferedReader(is);
String line = null;
String processMessage="";
while ((line = br.readLine()) != null) {
System.err.println("Line 1 "+line) ;
processMessage+=line;
}
System.out.println("Finished ");
is.close();
br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
But when I try the above code only the code up to page= webClient.getPage(locationToPing); is executed and gets blocked. "Start 5" is never printed on the screen.
I modifed the above code and instead of directly calling the e Java -jar command in the Runtime.exec(), I placed it in a batch file and called this batch file.
Process pr=Runtime.getRuntime().exec(batchFileLocation) ;
Now it executed as expected and didnt block the code.Also "Start 5" gets printed on the screen.
My application needs to invoke the jar periodically from java and destroy the previous process if any. So Option 4 doesnt hold good for me as the subprocess is stil alive and not very easy to destroy the subprocess.
Option 3 is the ideal way for me but am quite not able to understand why does it get blocked and doesnt proceed any longer? Is it something to do with threading? Am I using HTMLUnit the way how it is supposed to be used?
Thanks in Advance

Resources