How to Download Jars From Maven Central

| Comments

We know how to download Java libraries with it’s dependencies (transitive included) via Maven pom.xml, Ant/Ivy build.xml script, Gradle build.gradle script etc. But what if we need to download them without these scripts.

There are several ways to do this. Assume that we’d like to download spark-core library (groupId=com.sparkjava, artifactId=spark-core, version=2.1) with all dependencies from Maven Central into lib folder.

Use Maven3 dependency plugin

Here is there variants for lib download:

Download library with all dependencies
1
2
3
4
5
6
7
8
# Specify repoUrl (it's optional)
mvn dependency:get -DrepoUrl=http://download.java.net/maven/2/ -DgroupId=com.sparkjava -DartifactId=spark-core -Dversion=2.1

# OR use default repoUrl
mvn dependency:get -DgroupId=com.sparkjava -DartifactId=spark-core -Dversion=2.1

# OR use parameter artifact as groupId:artifactId:version
mvn dependency:get -Dartifact=com.sparkjava:spark-core:2.1

Now we need to copy just downloaded artifacts in our working directory:

Copy jars from local maven repo
1
2
3
mvn dependency:copy-dependencies -f $HOME/.m2/repository/com/sparkjava/spark-core/2.1/spark-core-2.1.pom -DoutputDirectory=$(pwd)/lib
# the previous command doesn't copy spark-core-x.x.jar, that's why we should copy it manually
cp $HOME/.m2/repository/com/sparkjava/spark-core/2.1/spark-core-2.1.jar $(pwd)/lib

Use standalone Ivy

We can use Ivy as standalone jar to download Maven dependencies without creating Ant build file:

1
2
3
4
5
# 1. Download the latest ivy jar (currently it's v.2.4.0)
curl -L -O http://search.maven.org/remotecontent?filepath=org/apache/ivy/ivy/2.4.0/ivy-2.4.0.jar

# 2. Run ivy.jar to retrieve all dependencies
java -jar ivy-2.4.0.jar -dependency com.sparkjava spark-core 2.1 -retrieve "lib/[artifact]-[revision](-[classifier]).[ext]"

As you can see Ivy downloads approach is much simpler. The only cons (or pros, it depends) that ivy.jar should be additionally downloaded.

Calling Ivy from Groovy or Java

Here I’ve decided to store Evgeny’s Goldin code snippet as a reference for myself. Programmatic artifacts downloads is not a common operation. It’s alway nice to know the general concept how it can be done. Especially when Ivy documentation is not very informative.

Groovy snippet of calling Ivy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import org.apache.ivy.Ivy
import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor
import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor
import org.apache.ivy.core.module.id.ModuleRevisionId
import org.apache.ivy.core.resolve.ResolveOptions
import org.apache.ivy.core.settings.IvySettings
import org.apache.ivy.plugins.resolver.URLResolver
import org.apache.ivy.core.report.ResolveReport
import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter


public File resolveArtifact(String groupId, String artifactId, String version) {
        //creates clear ivy settings
        IvySettings ivySettings = new IvySettings();
        //url resolver for configuration of maven repo
        URLResolver resolver = new URLResolver();
        resolver.setM2compatible(true);
        resolver.setName('central');
        //you can specify the url resolution pattern strategy
        resolver.addArtifactPattern(
            'http://repo1.maven.org/maven2/[organisation]/[module]/[revision]/[artifact](-[revision]).[ext]');
        //adding maven repo resolver
        ivySettings.addResolver(resolver);
        //set to the default resolver
        ivySettings.setDefaultResolver(resolver.getName());
        //creates an Ivy instance with settings
        Ivy ivy = Ivy.newInstance(ivySettings);

        File ivyfile = File.createTempFile('ivy', '.xml');
        ivyfile.deleteOnExit();

        String[] dep = [groupId, artifactId, version]

        DefaultModuleDescriptor md =
                DefaultModuleDescriptor.newDefaultInstance(ModuleRevisionId.newInstance(dep[0],
                dep[1] + '-caller', 'working'));

        DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(md,
                ModuleRevisionId.newInstance(dep[0], dep[1], dep[2]), false, false, true);
        md.addDependency(dd);

        //creates an ivy configuration file
        XmlModuleDescriptorWriter.write(md, ivyfile);

        String[] confs = ['default'];
        ResolveOptions resolveOptions = new ResolveOptions().setConfs(confs);

        //init resolve report
        ResolveReport report = ivy.resolve(ivyfile.toURL(), resolveOptions);

        //so you can get the jar library
        File jarArtifactFile = report.getAllArtifactsReports()[0].getLocalFile();

        return jarArtifactFile;
}

resolveArtifact( 'log4j', 'log4j', '1.2.16' )

References

How to Install Octopress on Windows?

| Comments

I’ve been using Octopress on Mac OS X (i.e. have no problem). But, recently I’ve decided to run my blog on Windows machine and felt pain. Ahh, Octopress uses bunch of native extentions which actually cause a lot of cross-platform issues. My first attempt was to try JRuby due to his better Windows support, but got this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ bundle install
Fetching gem metadata from https://rubygems.org/.........
Installing rake (10.4.2)
Installing RedCloth (4.2.9)
Using blankslate (2.1.2.4)
Installing hitimes (1.2.2)
Installing timers (4.0.1)
Installing celluloid (0.16.0)
Installing chunky_png (1.3.3)
Installing fast-stemmer (1.0.2) with native extensions
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension
.
        D:/Tools/JRuby/jruby-1.7.0/bin/jruby.exe extconf.rb NotImplementedError: C extension support is not enabled. Pass -Xcext.enabled=true to JRuby or set JRUBY_OPTS or modify .jrubyrc to enable.

   (root) at D:/Tools/JRuby/jruby-1.7.0/lib/ruby/shared/mkmf.rb:8  require at org/jruby/RubyKernel.java:1019
   (root) at D:/Tools/JRuby/jruby-1.7.0/lib/ruby/shared/rubygems/custom_require.rb:1
   (root) at extconf.rb:1


Gem files will remain installed in D:/Tools/JRuby/jruby-1.7.0/lib/ruby/gems/shared/gems/fast-stemmer-1.0.2 for inspection.
Results logged to D:/Tools/JRuby/jruby-1.7.0/lib/ruby/gems/shared/gems/fast-stemmer-1.0.2/ext/gem_make.out
An error occurred while installing fast-stemmer (1.0.2), and Bundler cannot continue.
Make sure that `gem install fast-stemmer -v '1.0.2'` succeeds before bundling.

There is JRuby version of fast-stemmer gem called jruby-stemmer. But, I’m not ready to maitain this. That’s why I’ve decided to use RubyInstaller.

Install Ruby on Windows and SSL issues

  1. Download (rubyinstaller-2.1.5-x64.exe in my case) and install RubyInstaller. I installed in d:\Tools\Ruby\Ruby21-x64\ folder.

  2. Check rubygems via running gem update and you should get the next error:

1
2
3
4
$ gem update
Updating installed gems
ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)
    SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (https://api.rubygems.org/specs.4.8.gz)

It’s well known rubygems issues with ready to use solution:

  • Step 1: Obtain the new trust certificate, download it AddTrustExternalCARoot-2048.pem in some temp folder
  • Step 2: Locate RubyGems certificate directory in your installation (in my case it’s D:/Tools/Ruby/Ruby21-x64/lib/ruby/2.1.0/ )
1
2
$ gem which rubygems
D:/Tools/Ruby/Ruby21-x64/lib/ruby/2.1.0/rubygems.rb
  • Step 3: Copy new trust certificate into D:\Tools\Ruby\Ruby21-x64\lib\ruby\2.1.0\rubygems\ssl_certs
1
$ copy AddTrustExternalCARoot-2048.pem D:\Tools\Ruby\Ruby21-x64\lib\ruby\2.1.0\rubygems\ssl_certs
  • Step 4: Now You should be able to run gem update without any issues

Prepapre environment for Octopress

Now it’s time to clone Octopress blog and run it. Unfortunatelly, there are some minor issues which still must be fixed.

Fix Octopress native extentions issues

We know that Octopress uses native extentions thats why we have to additionally install Development Kit

  • Download and unpack it in adjacent to Ruby install folder (d:\Tools\Ruby\DevKit_2.1_x64\ in my case)
  • Link Development Kit installation to previously installed Ruby
    • Go to Development Kit install folder d:\Tools\Ruby\DevKit_2.1_x64\
    • Run ruby dk.rb init which generate config.yml. Open config.yml and add - D:/Tools/Ruby/Ruby21-x64 to the end of this file.
    • Run ruby dk.rb install

See my Development Kit config.yml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# This configuration file contains the absolute path locations of all
# installed Rubies to be enhanced to work with the DevKit. This config
# file is generated by the 'ruby dk.rb init' step and may be modified
# before running the 'ruby dk.rb install' step. To include any installed
# Rubies that were not automagically discovered, simply add a line below
# the triple hyphens with the absolute path to the Ruby root directory.
#
# Example:
#
# ---
# - C:/ruby19trunk
# - C:/ruby192dev
#
---
- D:/Tools/Ruby/Ruby21-x64

Install Python

The default syntax highlighting engine in Octopress/Jekyll is Pygments. It’s requires Python v.2.7.x. Simply download Python v.2.7.8 and add it on system PATH.

Final steps

I assume that blog was previously cloned. Now, we should perform “traditional” Ruby project ceremony:

  • Install budler via gem install bundler
  • Setup all required gems bundle install
  • Run Octopress preview rake preview

References