10/21/2018

Subpixel anti-aliasing fonts of RHEL75: running IntelliJ IDEA in the remote VM (X11 over SSH) with subpixel anti-aliasing and hinting

It's been a while since my last post. New semester, new project, new technologies; this time I have to work on RHEL 7.5, so might expect some more posts like this.

RedHat introduced the developer program, which allows developers run a properly licensed RedHat Enterprise Linux on their developer machines.

Since I wanted to achieve proper OSX-like fonts when running X11 over SSH (to mirror a problem from work: IntelliJ IDEA running in a remote RHEL box X11 forwarded has blurry fonts), I installed the downloaded DVD image into a VirtualBox VM; I noticed running IntelliJ IDEA in the Gnome3 environment does not have proper hinting and subpixel-antialiasing already, resulting in blurred, distorted fonts.

My dev machine is running MacOS Sierra, and after properly setting up X via macports and setting all the proper parameters for X11 forwarding over SSH, when idea was started from a terminal in SSH, the fonts were the same blurry (e.g. grayscale-anti-aliased, you can check this via the OSX zoom tool by zooming close; if the edges of the line are colored blue-and-red, you are using subpixel already; if the edges are grey, you are obviously using grayscale only). So let's see which version of freetype RHEL is using, that's the library drawing the fonts:

mb:~ doma$ ssh root@rhel
Last login: Sun Oct 21 15:25:07 2018 from 192.168.0.34
[root@rhel ~]# yum list installed | grep freetype
freetype.x86_64                           2.4.11-15.el7            installed    
[root@rhel ~]# 

For me, it was freetype-2.4.11-15.el7. After a bit of searching over the net, it turns out RedHat turns off the bytecode-interpreter and the hinter in freetype by default... even more searching and, I came to the following commands (adapted from https://www.centos.org/forums/viewtopic.php?t=10564):

# original red hat enterprise linux 7.5
# install some pre-requisites
yum install yum-utils libX11-devel gcc rpm-build rpm-sign bzip2-devel libpng-devel
cd ~/tools
wget http://vault.centos.org/7.4.1708/os/Source/SPackages/freetype-2.4.11-15.el7.src.rpm
rpm -ivv freetype-2.4.11-15.el7.src.rpm
cd ~/rpmbuild/SPECS
rpmbuild --sign -ba --with bytecode_interpreter --with subpixel_rendering freetype.spec
# below to avoid "file /usr/lib64/libfreetype.so.6.10.0 from install of freetype-2.4.11-15.el7.x86_64 conflicts with file from package freetype-2.4.11-15.el7.x86_64"
rpm -e --nodeps freetype-2.4.11-15.el7.x86_64
rpm -Uh --replacepkgs ~/rpmbuild/RPMS/x86_64/freetype-2.4.11-15.el7.x86_64.rpm

If you have updated the system with yum update to - I guess here - RHEL7.6, the freetype version will be different. As of March, 2019 the following works perfectly:

yum install yum-utils libX11-devel gcc rpm-build rpm-sign bzip2-devel libpng-devel
cd ~/tools
wget https://mirror.chpc.utah.edu/pub/vault.centos.org/centos/7/updates/Source/SPackages/freetype-2.8-12.el7_6.1.src.rpm
rpm -ivv freetype-2.8-12.el7_6.1.src.rpm
cd ~/rpmbuild/SPECS
rpmbuild --sign -ba --with bytecode_interpreter --with subpixel_rendering freetype.spec
# below to avoid "file /usr/lib64/libfreetype.so.6.10.0 from install of freetype-2.8-12.el7_6.1.x86_64 conflicts with file from package freetype-2.8-12.el7_6.1.x86_64"
rpm -e --nodeps freetype-2.8-12.el7_6.1.x86_64
rpm -Uh --replacepkgs ~/rpmbuild/RPMS/x86_64/freetype-2.8-12.el7.1.x86_64.rpm

If you have updated the system with yum update to 7.7, the freetype version will again be different. As of Sept, 2019 the following works perfectly:

yum install yum-utils libX11-devel gcc rpm-build rpm-sign bzip2-devel libpng-devel
cd ~/tools
wget https://yum.oracle.com/repo/OracleLinux/OL7/latest/x86_64/getPackageSource/freetype-2.8-14.el7.src.rpm freetype-2.8-14.el7.src.rpm
rpm -ivv freetype-2.8-14.el7.src.rpm
cd ~/rpmbuild/SPECS
rpmbuild --sign -ba --with bytecode_interpreter --with subpixel_rendering freetype.spec
# below to avoid "file /usr/lib64/libfreetype.so.6.10.0 from install of freetype-2.8-14.el7.x86_64 conflicts with file from package freetype-2.8-14.el7.x86_64"
rpm -e --nodeps freetype-2.8-14.el7.x86_64
rpm -Uh --replacepkgs ~/rpmbuild/RPMS/x86_64/freetype-2.8-14.el7.x86_64.rpm

To configure the nice fonts (e.g. instruct the system to use the subpixel and hinting now enabled in freetype), add the following to /etc/fonts/local.conf :

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
  <!-- settings go here -->
  <match target="font">
    <edit name="antialias" mode="assign">
      <bool>true</bool>
    </edit>
  </match>
  <match target="font">
    <edit name="hinting" mode="assign">
      <bool>true</bool>
    </edit>
  </match>
  <match target="font">
    <edit name="autohint" mode="assign">
      <bool>false</bool>
    </edit>
  </match>
  <match target="font">
    <edit name="hintstyle" mode="assign">
      <const>hintslight</const>
    </edit>
  </match>
  <match target="font">
    <edit name="rgba" mode="assign">
      <const>rgb</const>
    </edit>
  </match>
  <match target="font">
    <edit name="lcdfilter" mode="assign">
      <const>lcddefault</const>
    </edit>
  </match>
</fontconfig>

This has fixed the blurry fonts in Gnome3 globally (as well as IntelliJ IDEA, so we're good to go) after a restart of the RHEL VM.

And the good news: this has also fixed the problem when running X11 over ssh:

mb:~ doma$ ssh -Y rhel
Last login: Sun Oct 21 15:12:05 2018 from 192.168.0.34
[doma@rhel ~]$ /opt/idea/bin/idea.sh 
Everything has changed
Everything has changed

And IntelliJ IDEA looks like this with Liberation fonts selected for UI:

That's a good start. Not quite like on osx, but close enough... This is when OSX is rendering, with the Optimus font:

With zoom it is apparent that both are using subpixel now.

This was OSX with the Optimus font. See the colorful edges? That's subpixel AA in action... And here comes the RHEL VM, rendered via Macport's X11 (but it would look the same in gnome - e.g in the native desktop environment - as earlier tests show...):

The difference is due to Retina display on my macbook; a quick xrandr reveals that XQuartz thinks we're running in 1680x1050, whilst the display's native resolution is 2880x1800. If you go to System Preferences -> Displays, under Resolution selecting Scaled -> More Space actually increases the fake resolution passed by OSX to X11 to 1920x200:

Last login: Tue Nov  6 20:01:43 on ttys004
            _     
           | |    
  _ __ ___ | |__  
 | '_ ` _ \| '_ \ 
 | | | | | | |_) |
 |_| |_| |_|_.__/
 
mb:~ doma$ xrandr -q
xrandr: Failed to get size of gamma for output default
Screen 0: minimum 640 x 480, current 1920 x 1200, maximum 3360 x 2100
default connected 1920x1200+0+0 0mm x 0mm
   2880x1800     60.00  
   1440x900      60.00  
   3360x2100     60.00  
   2560x1600     60.00  
   2048x1280     60.00  
   1650x1050     60.00  
   1280x800      60.00  
   1152x720      60.00  
   1024x768      60.00  
   840x524       60.00  
   800x600       60.00  
   640x480       60.00  
   1920x1178      1.00  
   1920x1200      2.00* 
mb:~ doma$ 

The screen looks much better like this. Some articles suggest that xrandr can actually change the resolution; in my case unfortunately there's a segmentation fault when trying to do so. So for the moment X11 will be displayed as such (not that bad anyway) - in my work, using MobaXTerm on Windows10 the fonts look quite good, not exhibiting the problem caused bby the retina display on osx.

Did it work for you? Please consider leaving a comment for others - maybe even with screenshot - , so they will be encouraged to rebuild their freetype as well given they consider the default grayscale antialiasing blurry.

5/18/2017

Building IntelliJ Idea Community edition on Ubuntu 16.10

Building IntelliJ Idea on Ubuntu is just a bit more complex than simply executing ant.

Acquiring dependencies

The commented lines below are required if you wish to use jdk1.6; in practice, things seem to build without (as of May, 2017 at least)

#sudo add-apt-repository ppa:webupd8team/java
#sudo apt-get update
#sudo apt-get install oracle-java6-installer
#sudo update-alternatives --config java
sudo apt-get install zlib1g-dev ant git
mkdir $HOME/tools
cd $HOME/tools
git clone git://git.jetbrains.org/idea/community.git idea
cd idea
./getPlugins.sh 
build/conf/install_nsis3.sh $HOME/tools/idea

If the build finishes with

...
scons: done building targets.
...the build of dependencies finished successfully.

Starting the build

If you've installed JDK1.6 (the commented lines above), here we need to refer to it (first line below). Again, IntelliJ Idea Community Edition builds without this, so left it commented out.

#export JDK_16_x64=/usr/lib/jvm/java-6-oracle
cd $HOME/tools/idea
ant

1/16/2017

Color-highlight given regex in MacOS 10.10 (Yosemite) or later

Using grep to filter commands' output is as easy as this:

mvn dependency:tree | grep selenium
Downloading: http://nexus.m44studio.com:8081/repository/maven-public/org/hpsl/common-selenium-integration-test/1.1.129-SNAPSHOT/maven-metadata.xml
Downloaded: http://nexus.m44studio.com:8081/repository/maven-public/org/hpsl/common-selenium-integration-test/1.1.129-SNAPSHOT/maven-metadata.xml (2 KB at 133.6 KB/sec)
[INFO] +- org.hpsl:common-selenium-integration-test:jar:1.1.129-SNAPSHOT:compile
[INFO] |  +- org.seleniumhq.selenium:selenium-firefox-driver:jar:3.0.1:compile
[INFO] |  |  \- org.seleniumhq.selenium:selenium-remote-driver:jar:3.0.1:compile
[INFO] |  |     +- org.seleniumhq.selenium:selenium-api:jar:3.0.1:compile
[INFO] |  \- org.seleniumhq.selenium:selenium-java:jar:3.0.1:compile
[INFO] |     +- org.seleniumhq.selenium:selenium-chrome-driver:jar:3.0.1:compile
[INFO] |     +- org.seleniumhq.selenium:selenium-edge-driver:jar:3.0.1:compile
[INFO] |     +- org.seleniumhq.selenium:selenium-ie-driver:jar:3.0.1:compile
[INFO] |     +- org.seleniumhq.selenium:selenium-opera-driver:jar:3.0.1:compile
[INFO] |     +- org.seleniumhq.selenium:selenium-safari-driver:jar:3.0.1:compile
[INFO] |     +- org.seleniumhq.selenium:selenium-support:jar:3.0.1:compile

Well as the example above is using maven to show dependencies for a given project, filtered only for selenium - what if you want to see all the dependencies, having selenium highlighted with color? Here we go:

mvn dependency:tree | grep --color -E 'selenium|$'
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ integration-tests ---
[INFO] com.doma.blueprint.cdi:integration-tests:jar:1.0.73-SNAPSHOT
[INFO] +- com.doma.blueprint.cdi:model:jar:1.0.73-SNAPSHOT:compile
[INFO] |  \- com.doma.annotations.blueprint.cdi:annotations:jar:1.0.73-SNAPSHOT:compile
[INFO] +- org.eclipse.persistence:org.eclipse.persistence.moxy:jar:2.6.0:compile
[INFO] |  +- org.eclipse.persistence:org.eclipse.persistence.core:jar:2.6.0:compile
[INFO] |  |  \- org.eclipse.persistence:org.eclipse.persistence.asm:jar:2.6.0:compile
[INFO] |  +- javax.validation:validation-api:jar:1.1.0.Final:compile
[INFO] |  \- org.glassfish:javax.json:jar:1.0.4:compile
[INFO] +- org.apache.httpcomponents:httpclient:jar:4.5.2:compile
[INFO] |  +- org.apache.httpcomponents:httpcore:jar:4.4.4:compile
[INFO] |  +- commons-logging:commons-logging:jar:1.2:compile
[INFO] |  \- commons-codec:commons-codec:jar:1.9:compile
[INFO] +- commons-httpclient:commons-httpclient:jar:3.1:compile
[INFO] +- junit:junit:jar:4.12:compile
[INFO] |  \- org.hamcrest:hamcrest-core:jar:1.3:compile
[INFO] +- org.slf4j:jcl-over-slf4j:jar:1.7.7:compile
[INFO] +- org.slf4j:log4j-over-slf4j:jar:1.7.5:compile
[INFO] +- ch.qos.logback:logback-classic:jar:1.1.3:compile
[INFO] |  \- ch.qos.logback:logback-core:jar:1.1.3:compile
[INFO] +- com.consol.citrus:citrus-core:jar:2.5.1:test
[INFO] |  +- com.consol.citrus.model:citrus-model-core:jar:2.5.1:test
[INFO] |  |  +- javax.xml.bind:jaxb-api:jar:2.2.11:test
[INFO] |  |  +- com.sun.xml.bind:jaxb-core:jar:2.2.11:test
[INFO] |  |  \- com.sun.xml.bind:jaxb-impl:jar:2.2.11:test
[INFO] |  +- commons-cli:commons-cli:jar:1.3.1:test
[INFO] |  +- commons-lang:commons-lang:jar:2.6:test
[INFO] |  +- xalan:xalan:jar:2.7.2:test
[INFO] |  |  \- xalan:serializer:jar:2.7.2:test
[INFO] |  +- xerces:xercesImpl:jar:2.11.0:test
[INFO] |  |  \- xml-apis:xml-apis:jar:1.4.01:test
[INFO] |  +- wsdl4j:wsdl4j:jar:1.6.3:test
[INFO] |  +- net.sf.jtidy:jtidy:jar:r938:test
[INFO] |  +- org.codehaus.groovy:groovy:jar:2.4.5:test
[INFO] |  +- org.codehaus.groovy:groovy-xml:jar:2.4.5:test
[INFO] |  +- org.codehaus.groovy:groovy-json:jar:2.4.5:test
[INFO] |  +- org.codehaus.groovy:groovy-jsr223:jar:2.4.5:test
[INFO] |  +- commons-logging:commons-logging-api:jar:1.1:test
[INFO] |  +- com.fasterxml.jackson.core:jackson-core:jar:2.6.3:test
[INFO] |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.6.3:test
[INFO] |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.6.3:test
[INFO] |  +- net.minidev:json-smart:jar:2.2.1:test
[INFO] |  |  \- net.minidev:accessors-smart:jar:1.1:test
[INFO] |  |     \- org.ow2.asm:asm:jar:5.0.3:test
[INFO] |  +- com.jayway.jsonpath:json-path:jar:2.0.0:test
[INFO] |  +- org.springframework:spring-core:jar:4.2.3.RELEASE:test
[INFO] |  +- org.springframework:spring-context:jar:4.2.3.RELEASE:test
[INFO] |  |  +- org.springframework:spring-aop:jar:4.2.3.RELEASE:test
[INFO] |  |  |  \- aopalliance:aopalliance:jar:1.0:test
[INFO] |  |  +- org.springframework:spring-beans:jar:4.2.3.RELEASE:test
[INFO] |  |  \- org.springframework:spring-expression:jar:4.2.3.RELEASE:test
[INFO] |  +- org.springframework:spring-jdbc:jar:4.2.3.RELEASE:test
[INFO] |  |  \- org.springframework:spring-tx:jar:4.2.3.RELEASE:test
[INFO] |  +- org.springframework.integration:spring-integration-core:jar:4.2.2.RELEASE:test
[INFO] |  |  +- org.springframework.retry:spring-retry:jar:1.1.2.RELEASE:test
[INFO] |  |  \- org.springframework:spring-messaging:jar:4.2.3.RELEASE:test
[INFO] |  +- org.springframework.ws:spring-xml:jar:2.2.3.RELEASE:test
[INFO] |  +- org.springframework:spring-oxm:jar:4.2.3.RELEASE:test
[INFO] |  \- org.springframework:spring-test:jar:4.2.3.RELEASE:test
[INFO] +- org.hpsl:common-selenium-integration-test:jar:1.1.129-SNAPSHOT:compile
[INFO] |  +- com.github.tntim96:JSCover:jar:1.0.24:compile
[INFO] |  |  \- org.mozilla:rhino:jar:1.7.7.1:compile
[INFO] |  +- org.seleniumhq.selenium:selenium-firefox-driver:jar:3.0.1:compile
[INFO] |  |  \- org.seleniumhq.selenium:selenium-remote-driver:jar:3.0.1:compile
[INFO] |  |     +- org.seleniumhq.selenium:selenium-api:jar:3.0.1:compile
[INFO] |  |     +- cglib:cglib-nodep:jar:3.2.4:compile
[INFO] |  |     +- org.apache.commons:commons-exec:jar:1.3:compile
[INFO] |  |     +- com.google.code.gson:gson:jar:2.3.1:compile
[INFO] |  |     +- com.google.guava:guava:jar:19.0:compile
[INFO] |  |     +- org.apache.httpcomponents:httpmime:jar:4.5.2:compile
[INFO] |  |     \- net.java.dev.jna:jna-platform:jar:4.1.0:compile
[INFO] |  |        \- net.java.dev.jna:jna:jar:4.1.0:compile
[INFO] |  +- com.codeborne:phantomjsdriver:jar:1.3.0:compile
[INFO] |  \- org.seleniumhq.selenium:selenium-java:jar:3.0.1:compile
[INFO] |     +- org.seleniumhq.selenium:selenium-chrome-driver:jar:3.0.1:compile
[INFO] |     +- org.seleniumhq.selenium:selenium-edge-driver:jar:3.0.1:compile
[INFO] |     +- org.seleniumhq.selenium:selenium-ie-driver:jar:3.0.1:compile
[INFO] |     +- org.seleniumhq.selenium:selenium-opera-driver:jar:3.0.1:compile
[INFO] |     +- org.seleniumhq.selenium:selenium-safari-driver:jar:3.0.1:compile
[INFO] |     |  \- io.netty:netty:jar:3.5.7.Final:compile
[INFO] |     +- org.seleniumhq.selenium:selenium-support:jar:3.0.1:compile
[INFO] |     +- net.sourceforge.htmlunit:htmlunit:jar:2.23:compile
[INFO] |     |  +- org.apache.commons:commons-lang3:jar:3.4:compile
[INFO] |     |  +- net.sourceforge.htmlunit:htmlunit-core-js:jar:2.23:compile
[INFO] |     |  +- net.sourceforge.htmlunit:neko-htmlunit:jar:2.23:compile
[INFO] |     |  +- net.sourceforge.cssparser:cssparser:jar:0.9.20:compile
[INFO] |     |  |  \- org.w3c.css:sac:jar:1.3:compile
[INFO] |     |  \- commons-io:commons-io:jar:2.5:compile
[INFO] |     \- org.eclipse.jetty.websocket:websocket-client:jar:9.2.15.v20160210:compile
[INFO] |        +- org.eclipse.jetty:jetty-util:jar:9.2.15.v20160210:compile
[INFO] |        +- org.eclipse.jetty:jetty-io:jar:9.2.15.v20160210:compile
[INFO] |        \- org.eclipse.jetty.websocket:websocket-common:jar:9.2.15.v20160210:compile
[INFO] |           \- org.eclipse.jetty.websocket:websocket-api:jar:9.2.15.v20160210:compile
[INFO] +- org.ops4j.pax.cdi:pax-cdi-api:jar:0.5.0:compile
[INFO] |  \- org.osgi:org.osgi.compendium:jar:4.3.1:compile
[INFO] +- javax.inject:javax.inject:jar:1:compile
[INFO] +- javax.transaction:javax.transaction-api:jar:1.2:compile
[INFO] +- org.hibernate.javax.persistence:hibernate-jpa-2.1-api:jar:1.0.0.Final:compile
[INFO] +- org.slf4j:slf4j-api:jar:1.7.7:compile
[INFO] +- org.osgi:org.osgi.core:jar:4.3.1:compile
[INFO] \- log4j:log4j:jar:1.2.17:test
Tested with Mac OSX 10.10 Yosemite. Enjoy!

10/21/2016

Gitlab on FreeBSD: Upgrading the port tree causes Shared object "libicui18n.so.55" not found, required by "charlock_holmes.so"

If you are just blindly updating FreeBDS's port tree with

portmaster --no-confirm -aD

Gitlab may fail to start due to a newer version of icui18n.so installed on the system, failing to find the old one.

This is how the error manifests itself:

# less ~/gitlab/log/unicorn.stderr.log

/usr/home/git/gitlab/vendor/bundle/ruby/2.2/gems/activesupport-4.1.11/lib/active_support/dependencies.rb:247:in `require': Shared object "libicui18n.so.55" not found, required by "charlock_holmes.so" - /usr/home/git/gitlab/vendor/bundle/ruby/2.2/gems/charlock_holmes-0.6.9.4/lib/charlock_holmes/charlock_holmes.so (LoadError)
        from /usr/home/git/gitlab/vendor/bundle/ruby/2.2/gems/activesupport-4.1.11/lib/active_support/dependencies.rb:247:in `block in require'
        from /usr/home/git/gitlab/vendor/bundle/ruby/2.2/gems/activesupport-4.1.11/lib/active_support/dependencies.rb:232:in `load_dependency'
        from /usr/home/git/gitlab/vendor/bundle/ruby/2.2/gems/activesupport-4.1.11/lib/active_support/dependencies.rb:247:in `require'
...

The fix is to reinstall the charlock_holmes gem, and then gitlab-shell:

cd gitlab
bundle exec gem uninstall charlock_holmes
bundle install
bundle exec rake gitlab:shell:setup RAILS_ENV=production

Then start gitlab (obviously with sudo rights):

service gitlab start

Feel free to drop a line below if the fix worked for you. Cheers!

References:

https://github.com/brianmario/charlock_holmes/issues/48

https://github.com/brianmario/charlock_holmes/issues/7

9/10/2016

Redmine fails to start: There was an error while trying to load the gem 'rbpdf'. Gem Load Error is: This installation of RMagick was configured with ImageMagick 6.9.4 but ImageMagick 6.9.5-5 is in use.

After redmine is installed and FreeBSD's package-tree was updated, Redmine did not start (with some nginx error in the browser), and investigating the error log:
less /var/log/nginx/error.log
...
  Message from application: There was an error while trying to load the gem 'rbpdf'.

Gem Load Error is: This installation of RMagick was configured with ImageMagick 6.9.4 but ImageMagick 6.9.5-5 is in use.

Backtrace for gem load error is:

/usr/local/lib/ruby/gems/2.2/gems/activesupport-4.2.7/lib/active_support/dependencies.rb:274:in `require'

/usr/local/lib/ruby/gems/2.2/gems/activesupport-4.2.7/lib/active_support/dependencies.rb:274:in `block in require'

/usr/local/lib/ruby/gems/2.2/gems/activesupport-4.2.7/lib/active_support/dependencies.rb:240:in `load_dependency'

/usr/local/lib/ruby/gems/2.2/gems/activesupport-4.2.7/lib/active_support/dependencies.rb:274:in `require'
...
led to the conclusion that we need to reinstall things here. So tried a remove of the concerned modules, and reinstalled the bundle:
cd /usr/local/www/redmine
gem uninstall rmagick
gem uninstall rpdf
bundle install
service nginx restart
And voila, redmine is back online.

11/26/2015

Updating FreeBSD's ports: a fully automated script to (slowly) rebuild everything

FreeBSD is a really good operating system to work with, but the daily process of keeping the port tree up-to-date could easily become a painful process.

Whenever any developer moves an important file between ports (happens a lot with Gnome3) a simple 'portmaster -a' will fail, complaining the old- and the new package willing to write to the same place.

You can always fix the issue by removing the whole package and reinstalling, but it breaks the anyway very long (e.g. hours) update procedure, and you'll have to wait another couple fo hours for the update to finish... Until you run into another package-move, and have to start over again.

After working with FreeBSD for a while, the most useful update procedure turns out to be similar to what they propose in 'man portmaster' :

     Using portmaster to do a complete reinstallation of all your ports:
           1. portmaster --list-origins > ~/installed-port-list
           2. Update your ports tree
           3. portmaster -ty --clean-distfiles
           4. portmaster --check-port-dbdir
           5. portmaster -Faf
           6. pkg_delete -a
           7. rm -rf /usr/local/lib/compat/pkg
           8. Back up any files in /usr/local you wish to save,
              such as configuration files in /usr/local/etc
           9. Manually check /usr/local and /var/db/pkg
              to make sure that they are really empty
           10. Re-install portmaster
           11. portmaster `cat ~/installed-port-list`

     You probably want to use the -D option for the installation and then run
     --clean-distfiles [-y] again when you are done.  You might also want to
     consider using the --force-config option when installing the new ports.

     Alternatively you could use portmaster -a -f -D to do an ``in place''
     update of your ports.  If that process is interrupted for any reason you
     can use portmaster -a -f -D -R to avoid rebuilding ports already rebuilt
     on previous runs.  However the first method (delete everything and rein-
     stall) is preferred.

Well, this painful (e.g. if you have lots of packages running on not-state-of-the-art hardware, could be up to 24 hours, or sometimes days) process really works. Whatever entanglement I've had with gnome packages - reinstalling everything obviously always helped.

Some time ago I bought 6 used DELL desktops to set up a home-made cluster, and today I had to update their packages, because I need to install a new port on them.

The automatic installation via 'portmaster -a' failed. As I really didn't want to go over the painful solving of the problem on each machine, I rather decided to use portmaster's documentation's suggestion, e.g. to reinstall everything on those rigs.

Which, unfurtonately turns out not to be completely automatic, and rather uncomfortable. The automatism is jeopardized by portmaster and some other tools stopping and asking for the user's confirmation over tty1, which again breaks a very long procedure.

Since the original inception of portmaster they might had different default swithches, but as of FreeBSD 10.1 and 10.2, the following script turns out to be working without interruption:

portmaster --list-origins > ~/installed-port-list
portsnap fetch update
# backup /var/db/ports with our existing options
cd /var/db
tar cvzf ports.tar.gz ports
portmaster -ty --clean-distfiles
portmaster --check-port-dbdir -y
portmaster -Faf
pkg delete -a -y
rm -rf /usr/local/lib/compat/pkg
rm -rf /var/db/pkg
cd /var/db
tar xvzf ports.tar.gz
cd /usr/ports/ports-mgmt/pkg
make install clean
cd /usr/ports/ports-mgmt/portmaster
make install clean
cd ~
portmaster -d -y --no-confirm --delete-packages --update-if-newer `cat ~/installed-port-list`

The changes needed were mainly the portmaster flags, but the /var/db/ports tree is also backed up & restored: that's the location where the answers to those blue 'dialog4ports' windows' are stored:

...
cd /var/db
tar cvzf ports.tar.gz ports
...
cd /var/db
tar xvzf ports.tar.gz
...

It is very long to do it this way, as we delete and recompile every package of the system. But as it can be completely automated with the script above, I don't mind letting the computer do it's job overnight if that saves me some trouble - e.g. solving version-issues between recently updated FreeBSD port packages...

Let us know how you manage to automatically update your FreeBSD boxes in the comment section below. Portmaster's suggestion is "brutal", but is quite effective in the end... I'm sure there are other solutions as well.


11/23/2015

Apache Karaf: no matching cipher found: client aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se server

During a recent deployment of a custom Karaf distribution via the karaf-maven-plugin, I've experienced a very strange behaviour when deployed to FreeBSD rather than my developer Mac OS rig.

Connecting thru SSH failed, so the logging has been increased:

dfi:~ doma$ ssh karaf@optiplex1 -p 8100
no matching cipher found: client aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se server 

Here's Karaf's exception logged:

16:24:03,890 INFO  8]-nio2-thread-1 125 shd.server.session.ServerSession Server session created from /192.168.0.21:64951
16:24:03,894 DEBUG 8]-nio2-thread-1 125 shd.server.session.ServerSession Client version string: SSH-2.0-OpenSSH_6.2
16:24:03,900 DEBUG 8]-nio2-thread-1 125 d.common.session.AbstractSession Send SSH_MSG_KEXINIT
16:24:03,901 DEBUG 8]-nio2-thread-1 125 d.common.session.AbstractSession Received SSH_MSG_KEXINIT
16:24:03,902 WARN  8]-nio2-thread-1 125 d.common.session.AbstractSession Exception caught
jjava.lang.IllegalStateException: Unable to negotiate key exchange for encryption algorithms (client to server) (client: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lys
ator.liu.se / server: )
        at org.apache.sshd.common.session.AbstractSession.negotiate(AbstractSession.java:1159)[125:org.apache.sshd.core:0.14.0]
        at org.apache.sshd.common.session.AbstractSession.doHandleMessage(AbstractSession.java:388)[125:org.apache.sshd.core:0.14.0]
        at org.apache.sshd.common.session.AbstractSession.handleMessage(AbstractSession.java:326)[125:org.apache.sshd.core:0.14.0]
        at org.apache.sshd.common.session.AbstractSession.decode(AbstractSession.java:780)[125:org.apache.sshd.core:0.14.0]
        at org.apache.sshd.common.session.AbstractSession.messageReceived(AbstractSession.java:308)[125:org.apache.sshd.core:0.14.0]
        at org.apache.sshd.common.AbstractSessionIoHandler.messageReceived(AbstractSessionIoHandler.java:54)
        at org.apache.sshd.common.io.nio2.Nio2Session$1.onCompleted(Nio2Session.java:184)
        at org.apache.sshd.common.io.nio2.Nio2Session$1.onCompleted(Nio2Session.java:170)
        at org.apache.sshd.common.io.nio2.Nio2CompletionHandler$1.run(Nio2CompletionHandler.java:32)
        at java.security.AccessController.doPrivileged(Native Method)[:1.8.0_60]
        at org.apache.sshd.common.io.nio2.Nio2CompletionHandler.completed(Nio2CompletionHandler.java:30)[125:org.apache.sshd.core:0.14.0]
        at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126)[:1.8.0_60]
        at sun.nio.ch.Invoker.invokeDirect(Invoker.java:157)[:1.8.0_60]
        at sun.nio.ch.UnixAsynchronousSocketChannelImpl.implRead(UnixAsynchronousSocketChannelImpl.java:553)[:1.8.0_60]
        at sun.nio.ch.AsynchronousSocketChannelImpl.read(AsynchronousSocketChannelImpl.java:276)[:1.8.0_60]
        at sun.nio.ch.AsynchronousSocketChannelImpl.read(AsynchronousSocketChannelImpl.java:297)[:1.8.0_60]
        at java.nio.channels.AsynchronousSocketChannel.read(AsynchronousSocketChannel.java:420)[:1.8.0_60]
        at org.apache.sshd.common.io.nio2.Nio2Session.startReading(Nio2Session.java:170)[125:org.apache.sshd.core:0.14.0]
        at org.apache.sshd.common.io.nio2.Nio2Acceptor$AcceptCompletionHandler.onCompleted(Nio2Acceptor.java:135)[125:org.apache.sshd.core:0.14.0]
        at org.apache.sshd.common.io.nio2.Nio2Acceptor$AcceptCompletionHandler.onCompleted(Nio2Acceptor.java:120)[125:org.apache.sshd.core:0.14.0]
        at org.apache.sshd.common.io.nio2.Nio2CompletionHandler$1.run(Nio2CompletionHandler.java:32)
        at java.security.AccessController.doPrivileged(Native Method)[:1.8.0_60]
        at org.apache.sshd.common.io.nio2.Nio2CompletionHandler.completed(Nio2CompletionHandler.java:30)[125:org.apache.sshd.core:0.14.0]
        at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126)[:1.8.0_60]
        at sun.nio.ch.Invoker$2.run(Invoker.java:218)[:1.8.0_60]
        at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)[:1.8.0_60]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)[:1.8.0_60]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)[:1.8.0_60]
        at java.lang.Thread.run(Thread.java:745)[:1.8.0_60]

After trying out all sort of tips read via google, finally realized: setting the JAVA_HOME fixes the issue. To solve for all users I added this line to /etc/profile:

export JAVA_HOME=/usr/local/openjdk7

You can also put the same line to $HOME/.profile to fix it only for one user.

Karaf is beautiful but this one was ugly. Well, my fault: starting Karaf actually complains about not setting JAVA_HOME (and that results may vary), but since I used it like that for quite a while, didn't expect this.

9/08/2015

Starting Karaf 4 results in java.lang.ClassNotFoundException: org.apache.karaf.main.Main

When you try to start Karaf and you'll get

#dell:apache-karaf-4.0.1 doma$ bin/karaf 
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/karaf/main/Main
Caused by: java.lang.ClassNotFoundException: org.apache.karaf.main.Main
 at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
 at java.security.AccessController.doPrivileged(Native Method)
 at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
 at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:247)

...there's a good chance that it is caused by an incorrect KARAF_HOME:

#dell:apache-karaf-4.0.1 doma$ bin/karaf 
Error: Could not find or load main class org.apache.karaf.main.Main
#dell:apache-karaf-4.0.1 doma$ set | grep KARAF
KARAF_HOME=/opt/karaf
#dell:apache-karaf-4.0.1 doma$ unset KARAF_HOME
#dell:apache-karaf-4.0.1 doma$ set | grep KARAF
_=KARAF_HOME
#dell:apache-karaf-4.0.1 doma$ bin/karaf 
        __ __                  ____      
       / //_/____ __________ _/ __/      
      / ,<  / __ `/ ___/ __ `/ /_        
     / /| |/ /_/ / /  / /_/ / __/        
    /_/ |_|\__,_/_/   \__,_/_/         

  Apache Karaf (4.0.1)

Hit '' for a list of available commands
and '[cmd] --help' for help on a specific command.
Hit '' or type 'system:shutdown' or 'logout' to shutdown Karaf.

karaf@root()>

7/16/2015

Building Hadoop 2.4.0 on Mac OS X Yosemite 10.10.3 with native components

Install pre-requisites

We'll need these for the actual build.

sudo port install cmake gmake gcc48 zlib gzip maven32 apache-ant

Install protobuf 2.5.0

As the current latest version in macports is 2.6.x, we need to stick to an earlier version:

cd ~/tools
svn co http://svn.macports.org/repository/macports/trunk/dports/devel/protobuf-cpp -r 105333
cd protobuf-cpp/
sudo port install

To verify:

protoc --version
# libprotoc 2.5.0

Acquire sources

As I needed an exact version for my work to reproduce an issue, I'll go with version 2.4.0 for now. I suppose some of the fixes will work with earlier or later versions as well. Look around in the tags folder for other versions.

cd ~/dev
svn co http://svn.apache.org/repos/asf/hadoop/common/tags/release-2.4.0 hadoop-2.4.0
cd hadoop-2.4.0

Fix sources

We need to patch JniBasedUnixGroupsNetgroupMapping:

patch -p0 <<EOF
--- hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c.orig 2015-07-16 17:14:20.000000000 +0200
+++ hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c 2015-07-16 17:17:47.000000000 +0200
@@ -74,7 +74,7 @@
   // endnetgrent)
   setnetgrentCalledFlag = 1;
 #ifndef __FreeBSD__
-  if(setnetgrent(cgroup) == 1) {
+  setnetgrent(cgroup); {
 #endif
     current = NULL;
     // three pointers are for host, user, domain, we only care

EOF

As well as container-executor.c:

patch -p0 <<EOF
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c.orig 2015-07-16 17:49:15.000000000 +0200
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c 2015-07-16 18:13:03.000000000 +0200
@@ -498,7 +498,7 @@
   char **users = whitelist;
   if (whitelist != NULL) {
     for(; *users; ++users) {
-      if (strncmp(*users, user, LOGIN_NAME_MAX) == 0) {
+      if (strncmp(*users, user, 64) == 0) {
         free_values(whitelist);
         return 1;
       }
@@ -1247,7 +1247,7 @@
               pair);
     result = -1; 
   } else {
-    if (mount("none", mount_path, "cgroup", 0, controller) == 0) {
+    if (mount("none", mount_path, "cgroup", 0) == 0) {
       char *buf = stpncpy(hier_path, mount_path, strlen(mount_path));
       *buf++ = '/';
       snprintf(buf, PATH_MAX - (buf - hier_path), "%s", hierarchy);
@@ -1274,3 +1274,21 @@
   return result;
 }
 
+int fcloseall(void)
+{
+    int succeeded; /* return value */
+    FILE *fds_to_close[3]; /* the size being hardcoded to '3' is temporary */
+    int i; /* loop counter */
+    succeeded = 0;
+    fds_to_close[0] = stdin;
+    fds_to_close[1] = stdout;
+    fds_to_close[2] = stderr;
+    /* max iterations being hardcoded to '3' is temporary: */
+    for ((i = 0); (i < 3); i++) {
+ succeeded += fclose(fds_to_close[i]);
+    }
+    if (succeeded != 0) {
+ succeeded = EOF;
+    }
+    return succeeded;
+}

EOF

Install Oracle JDK 1.7

You'll need to install "Java SE Development Kit 7 (Mac OS X x64)" from Oracle. Then let's fix some things expected by the build at a different place:

export JAVA_HOME=`/usr/libexec/java_home -v 1.7`
sudo mkdir $JAVA_HOME/Classes
sudo ln -s $JAVA_HOME/lib/tools.jar $JAVA_HOME/Classes/classes.jar

Install Hadoop 2.4.0:

Sooner or later we've been expected to get here, right?

mvn package -Pdist,native -DskipTests -Dtar

If all goes well:

main:
     [exec] $ tar cf hadoop-2.4.0.tar hadoop-2.4.0
     [exec] $ gzip -f hadoop-2.4.0.tar
     [exec] 
     [exec] Hadoop dist tar available at: /Users/doma/dev/hadoop-2.4.0/hadoop-dist/target/hadoop-2.4.0.tar.gz
     [exec] 
[INFO] Executed tasks
[INFO] 
[INFO] --- maven-javadoc-plugin:2.8.1:jar (module-javadocs) @ hadoop-dist ---
[INFO] Building jar: /Users/doma/dev/hadoop-2.4.0/hadoop-dist/target/hadoop-dist-2.4.0-javadoc.jar
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] Apache Hadoop Main ................................ SUCCESS [1.177s]
[INFO] Apache Hadoop Project POM ......................... SUCCESS [1.548s]
[INFO] Apache Hadoop Annotations ......................... SUCCESS [3.394s]
[INFO] Apache Hadoop Assemblies .......................... SUCCESS [0.277s]
[INFO] Apache Hadoop Project Dist POM .................... SUCCESS [1.765s]
[INFO] Apache Hadoop Maven Plugins ....................... SUCCESS [3.143s]
[INFO] Apache Hadoop MiniKDC ............................. SUCCESS [2.498s]
[INFO] Apache Hadoop Auth ................................ SUCCESS [3.265s]
[INFO] Apache Hadoop Auth Examples ....................... SUCCESS [2.074s]
[INFO] Apache Hadoop Common .............................. SUCCESS [1:26.460s]
[INFO] Apache Hadoop NFS ................................. SUCCESS [4.527s]
[INFO] Apache Hadoop Common Project ...................... SUCCESS [0.032s]
[INFO] Apache Hadoop HDFS ................................ SUCCESS [2:09.326s]
[INFO] Apache Hadoop HttpFS .............................. SUCCESS [14.876s]
[INFO] Apache Hadoop HDFS BookKeeper Journal ............. SUCCESS [5.814s]
[INFO] Apache Hadoop HDFS-NFS ............................ SUCCESS [2.941s]
[INFO] Apache Hadoop HDFS Project ........................ SUCCESS [0.034s]
[INFO] hadoop-yarn ....................................... SUCCESS [0.034s]
[INFO] hadoop-yarn-api ................................... SUCCESS [57.713s]
[INFO] hadoop-yarn-common ................................ SUCCESS [20.985s]
[INFO] hadoop-yarn-server ................................ SUCCESS [0.040s]
[INFO] hadoop-yarn-server-common ......................... SUCCESS [6.935s]
[INFO] hadoop-yarn-server-nodemanager .................... SUCCESS [12.889s]
[INFO] hadoop-yarn-server-web-proxy ...................... SUCCESS [2.362s]
[INFO] hadoop-yarn-server-applicationhistoryservice ...... SUCCESS [4.059s]
[INFO] hadoop-yarn-server-resourcemanager ................ SUCCESS [11.368s]
[INFO] hadoop-yarn-server-tests .......................... SUCCESS [0.467s]
[INFO] hadoop-yarn-client ................................ SUCCESS [4.109s]
[INFO] hadoop-yarn-applications .......................... SUCCESS [0.043s]
[INFO] hadoop-yarn-applications-distributedshell ......... SUCCESS [2.123s]
[INFO] hadoop-yarn-applications-unmanaged-am-launcher .... SUCCESS [1.902s]
[INFO] hadoop-yarn-site .................................. SUCCESS [0.030s]
[INFO] hadoop-yarn-project ............................... SUCCESS [3.828s]
[INFO] hadoop-mapreduce-client ........................... SUCCESS [0.069s]
[INFO] hadoop-mapreduce-client-core ...................... SUCCESS [19.507s]
[INFO] hadoop-mapreduce-client-common .................... SUCCESS [13.039s]
[INFO] hadoop-mapreduce-client-shuffle ................... SUCCESS [2.232s]
[INFO] hadoop-mapreduce-client-app ....................... SUCCESS [7.625s]
[INFO] hadoop-mapreduce-client-hs ........................ SUCCESS [6.198s]
[INFO] hadoop-mapreduce-client-jobclient ................. SUCCESS [5.440s]
[INFO] hadoop-mapreduce-client-hs-plugins ................ SUCCESS [1.534s]
[INFO] Apache Hadoop MapReduce Examples .................. SUCCESS [4.577s]
[INFO] hadoop-mapreduce .................................. SUCCESS [2.903s]
[INFO] Apache Hadoop MapReduce Streaming ................. SUCCESS [3.509s]
[INFO] Apache Hadoop Distributed Copy .................... SUCCESS [6.723s]
[INFO] Apache Hadoop Archives ............................ SUCCESS [1.705s]
[INFO] Apache Hadoop Rumen ............................... SUCCESS [4.460s]
[INFO] Apache Hadoop Gridmix ............................. SUCCESS [3.330s]
[INFO] Apache Hadoop Data Join ........................... SUCCESS [2.585s]
[INFO] Apache Hadoop Extras .............................. SUCCESS [2.361s]
[INFO] Apache Hadoop Pipes ............................... SUCCESS [9.603s]
[INFO] Apache Hadoop OpenStack support ................... SUCCESS [3.797s]
[INFO] Apache Hadoop Client .............................. SUCCESS [6.102s]
[INFO] Apache Hadoop Mini-Cluster ........................ SUCCESS [0.091s]
[INFO] Apache Hadoop Scheduler Load Simulator ............ SUCCESS [3.251s]
[INFO] Apache Hadoop Tools Dist .......................... SUCCESS [5.068s]
[INFO] Apache Hadoop Tools ............................... SUCCESS [0.032s]
[INFO] Apache Hadoop Distribution ........................ SUCCESS [24.974s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8:54.425s
[INFO] Finished at: Thu Jul 16 18:22:12 CEST 2015
[INFO] Final Memory: 173M/920M
[INFO] ------------------------------------------------------------------------

Using it

First we'll extract the results of our build. Then actually there is a little bit of configuration needed even for a single-cluster setup. Don't worry, I'll copy it here for your comfort ;-)

tar -xvzf /Users/doma/dev/hadoop-2.4.0/hadoop-dist/target/hadoop-2.4.0.tar.gz -C ~/tools

The contents of ~/tools/hadoop-2.4.0/etc/hadoop/core-site.xml:

<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://localhost:9000</value>
    </property>
</configuration>

The contents of ~/tools/hadoop-2.4.0/etc/hadoop/hdfs-site.xml:

<configuration>
    <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>
</configuration>

Passwordless SSH

From the official docs:

ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys

Starting up

Let's see what we've did. This is a raw copy from the official docs.

  1. Format the filesystem:
    bin/hdfs namenode -format
    
  2. Start NameNode daemon and DataNode daemon:
    sbin/start-dfs.sh
    

    The hadoop daemon log output is written to the $HADOOP_LOG_DIR directory (defaults to $HADOOP_HOME/logs).

  3. Browse the web interface for the NameNode; by default it is available at:
  4. Make the HDFS directories required to execute MapReduce jobs:
    bin/hdfs dfs -mkdir /user
    bin/hdfs dfs -mkdir /user/<username>
    
  5. Copy the input files into the distributed filesystem:
    bin/hdfs dfs -put etc/hadoop input
    

    Check if they are there at http://localhost:50070/explorer.html#/

  6. Run some of the examples provided (that's actually one line...):
    bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.4.0.jar grep input output 'dfs[a-z.]+'
    
  7. Examine the output files:

    Copy the output files from the distributed filesystem to the local filesystem and examine them:

    bin/hdfs dfs -get output output
    cat output/*
    

    or

    View the output files on the distributed filesystem:

    bin/hdfs dfs -cat output/*
    
  8. When you're done, stop the daemons with:
    sbin/stop-dfs.sh
    

Possible errors without the fixes & tweaks above

This list is an excerpt from my efforts during the build. They meant to drive you here via google ;-) Apply the procedure above and all of these errors will be fixed for you.

Without ProtoBuf

If you don't have protobuf, you'll get the following error:

[INFO] --- hadoop-maven-plugins:2.4.0:protoc (compile-protoc) @ hadoop-common ---
[WARNING] [protoc, --version] failed: java.io.IOException: Cannot run program "protoc": error=2, No such file or directory
[ERROR] stdout: []

Wrong version of ProtoBuf

If you don't have the correct version of protobuf, you'll get

[ERROR] Failed to execute goal org.apache.hadoop:hadoop-maven-plugins:2.4.0:protoc (compile-protoc) on project hadoop-common: org.apache.maven.plugin.MojoExecutionException: protoc version is 'libprotoc 2.6.1', expected version is '2.5.0' -> [Help 1]

CMAKE missing

If you don't have cmake, you'll get

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.7:run (make) on project hadoop-common: An Ant BuildException has occured: Execute failed: java.io.IOException: Cannot run program "cmake" (in directory "/Users/doma/dev/hadoop-2.4.0/hadoop-common-project/hadoop-common/target/native"): error=2, No such file or directory
[ERROR] around Ant part ...... @ 4:132 in /Users/doma/dev/hadoop-2.4.0/hadoop-common-project/hadoop-common/target/antrun/build-main.xml

JAVA_HOME missing

If you don't have JAVA_HOME correctly set, you'll get

     [exec] -- Detecting CXX compiler ABI info
     [exec] -- Detecting CXX compiler ABI info - done
     [exec] -- Detecting CXX compile features
     [exec] -- Detecting CXX compile features - done
     [exec] CMake Error at /opt/local/share/cmake-3.2/Modules/FindPackageHandleStandardArgs.cmake:138 (message):
     [exec]   Could NOT find JNI (missing: JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY
     [exec]   JAVA_INCLUDE_PATH JAVA_INCLUDE_PATH2 JAVA_AWT_INCLUDE_PATH)
     [exec] Call Stack (most recent call first):
     [exec]   /opt/local/share/cmake-3.2/Modules/FindPackageHandleStandardArgs.cmake:374 (_FPHSA_FAILURE_MESSAGE)
     [exec]   /opt/local/share/cmake-3.2/Modules/FindJNI.cmake:287 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
     [exec]   JNIFlags.cmake:117 (find_package)
     [exec]   CMakeLists.txt:24 (include)
     [exec] 
     [exec] 
     [exec] -- Configuring incomplete, errors occurred!
     [exec] See also "/Users/doma/dev/hadoop-2.4.0/hadoop-common-project/hadoop-common/target/native/CMakeFiles/CMakeOutput.log".

JniBasedUnixGroupsNetgroupMapping.c patch missing

If you don't have the patch for JniBasedUnixGroupsNetgroupMapping.c above, you'll get

     [exec] [ 38%] Building C object CMakeFiles/hadoop.dir/main/native/src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c.o
     [exec] /Library/Developer/CommandLineTools/usr/bin/cc  -Dhadoop_EXPORTS -g -Wall -O2 -D_REENTRANT -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC -I/Users/doma/dev/hadoop-2.4.0/hadoop-common-project/hadoop-common/target/native/javah -I/Users/doma/dev/hadoop-2.4.0/hadoop-common-project/hadoop-common/src/main/native/src -I/Users/doma/dev/hadoop-2.4.0/hadoop-common-project/hadoop-common/src -I/Users/doma/dev/hadoop-2.4.0/hadoop-common-project/hadoop-common/src/src -I/Users/doma/dev/hadoop-2.4.0/hadoop-common-project/hadoop-common/target/native -I/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/include/darwin -I/opt/local/include -I/Users/doma/dev/hadoop-2.4.0/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/util    -o CMakeFiles/hadoop.dir/main/native/src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c.o   -c /Users/doma/dev/hadoop-2.4.0/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c
     [exec] /Users/doma/dev/hadoop-2.4.0/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c:77:26: error: invalid operands to binary expression ('void' and 'int')
     [exec]   if(setnetgrent(cgroup) == 1) {
     [exec]      ~~~~~~~~~~~~~~~~~~~ ^  ~
     [exec] 1 error generated.
     [exec] make[2]: *** [CMakeFiles/hadoop.dir/main/native/src/org/apache/hadoop/security/JniBasedUnixGroupsNetgroupMapping.c.o] Error 1
     [exec] make[1]: *** [CMakeFiles/hadoop.dir/all] Error 2
     [exec] make: *** [all] Error 2

fcloseall patch missing

Without applying the fcloseall patch above, you might get the following error:

     [exec] Undefined symbols for architecture x86_64:
     [exec]   "_fcloseall", referenced from:
     [exec]       _launch_container_as_user in libcontainer.a(container-executor.c.o)
     [exec] ld: symbol(s) not found for architecture x86_64
     [exec] collect2: error: ld returned 1 exit status
     [exec] make[2]: *** [target/usr/local/bin/container-executor] Error 1
     [exec] make[1]: *** [CMakeFiles/container-executor.dir/all] Error 2
     [exec] make: *** [all] Error 2

Symlink missing

Without the "export JAVA_HOME=`/usr/libexec/java_home -v 1.7`;sudo mkdir $JAVA_HOME/Classes;sudo ln -s $JAVA_HOME/lib/tools.jar $JAVA_HOME/Classes/classes.jar" line creating the symlinks above, you'll get

Exception in thread "main" java.lang.AssertionError: Missing tools.jar at: /Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/Classes/classes.jar. Expression: file.exists()
 at org.codehaus.groovy.runtime.InvokerHelper.assertFailed(InvokerHelper.java:395)
 at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.assertFailed(ScriptBytecodeAdapter.java:683)
 at org.codehaus.mojo.jspc.CompilationMojoSupport.findToolsJar(CompilationMojoSupport.groovy:371)
 at org.codehaus.mojo.jspc.CompilationMojoSupport.this$4$findToolsJar(CompilationMojoSupport.groovy)
...

References:

http://java-notes.com/index.php/hadoop-on-osx

https://issues.apache.org/jira/secure/attachment/12602452/HADOOP-9350.patch

http://www.csrdu.org/nauman/2014/01/23/geting-started-with-hadoop-2-2-0-building/

https://developer.apple.com/library/mac/documentation/Porting/Conceptual/PortingUnix/compiling/compiling.html

https://github.com/cooljeanius/libUnixToOSX/blob/master/fcloseall.c

http://hadoop.apache.org/docs/r2.4.1/hadoop-project-dist/hadoop-common/SingleCluster.html


Install Apache Ant 1.8.1 via MacPorts

If the latest version of Apache Ant in MacPorts is not what you're after, you can try to downgrade. Here's how simple it is:

cd ~/tools
svn co http://svn.macports.org/repository/macports/trunk/dports/devel/apache-ant -r 74985
cd apache-ant/
sudo port install

To verify:

# ant -version
# Apache Ant version 1.8.1 compiled on April 30 2010

If you want to get other revisions, see here.

Switch between versions

But wait, there's more! You can even switch between the different versions installed easily. Actually this is what makes the whole process comfortable, no need to store different versions of tools at arbitrary locations...

sudo port activate apache-ant
--->  The following versions of apache-ant are currently installed:
--->      apache-ant @1.8.1_1 (active)
--->      apache-ant @1.8.4_0
--->      apache-ant @1.9.4_0
Error: port activate failed: Registry error: Please specify the full version as recorded in the port registry.

I have these three versions - I used 1.8.4 for the earlier Tomcat build, and 1.8.1 for the Hadoop build (the next post...)

But now that Hadoop is also built on OSX for my work, I switch back to the latest version:

sudo port activate apache-ant@1.9.4_0
--->  Deactivating apache-ant @1.8.1_1
--->  Cleaning apache-ant
--->  Activating apache-ant @1.9.4_0
--->  Cleaning apache-ant

To verify:

ant -version
# Apache Ant(TM) version 1.9.4 compiled on April 29 2014

Neat, huh?

6/18/2015

Downgrading MacPorts: use Ant 1.8.4 to build Tomcat 6 in Yosemite 10.10.3

Building Tomcat6 on MacPorts fails on building jakarta-taglibs-standard-11 due to Maven 1.9.4 present in the MacPorts repo. The error manifests itself like this:

...
    [javac] /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_java_jakarta-taglibs-standard-11/jakarta-taglibs-standard-11/work/jakarta-taglibs-standard-1.1.2-src/standard/build.xml:178: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
    [javac] Compiling 236 source files to /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_java_jakarta-taglibs-standard-11/jakarta-taglibs-standard-11/work/jakarta-taglibs-standard-1.1.2-src/standard/build/standard/standard/classes
    [javac] Fatal Error: Unable to find package java.lang in classpath or bootclasspath
BUILD FAILED
/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_java_jakarta-taglibs-standard-11/jakarta-taglibs-standard-11/work/jakarta-taglibs-standard-1.1.2-src/standard/build.xml:178: Compile failed; see the compiler error output for details.
...

The build can be fixed by downgrading Ant:

cd ~
svn co -r 94758 http://svn.macports.org/repository/macports/trunk/dports/devel/apache-ant
cd apache-ant
sudo port install

Now tomcat can be installed from ports:

sudo port install tomcat6

Starting tomcat now shows we need some further customization:

# sudo port load tomcat6
# sudo less /opt/local/share/java/tomcat6/logs/catalina.err
2015-06-17 20:25:42.976 jsvc[587:5132] Apple AWT Java VM was loaded on first thread -- can't start AWT.
Jun 17, 2015 8:25:42 PM org.apache.catalina.startup.Bootstrap initClassLoaders
SEVERE: Class loader creation threw exception
java.lang.InternalError: Can't start the AWT because Java was started on the first thread.  Make sure StartOnFirstThread is not specified in your application's Info.plist or on the command line
        at java.lang.ClassLoader$NativeLibrary.load(Native Method)
        at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1833)
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1730)
        at java.lang.Runtime.loadLibrary0(Runtime.java:823)
        at java.lang.System.loadLibrary(System.java:1044)
        at sun.security.action.LoadLibraryAction.run(LoadLibraryAction.java:50)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.awt.Toolkit.loadLibraries(Toolkit.java:1605)
        at java.awt.Toolkit.(Toolkit.java:1627)
        at sun.awt.AppContext$2.run(AppContext.java:240)
        at sun.awt.AppContext$2.run(AppContext.java:226)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.awt.AppContext.initMainAppContext(AppContext.java:226)
        at sun.awt.AppContext.access$200(AppContext.java:112)
        at sun.awt.AppContext$3.run(AppContext.java:306)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.awt.AppContext.getAppContext(AppContext.java:287)
        at com.sun.jmx.trace.Trace.out(Trace.java:180)
        at com.sun.jmx.trace.Trace.isSelected(Trace.java:88)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.isTraceOn(DefaultMBeanServerInterceptor.java:1830)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerDynamicMBean(DefaultMBeanServerInterceptor.java:929)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerObject(DefaultMBeanServerInterceptor.java:916)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(DefaultMBeanServerInterceptor.java:312)
        at com.sun.jmx.mbeanserver.JmxMBeanServer$2.run(JmxMBeanServer.java:1195)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.initialize(JmxMBeanServer.java:1193)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.(JmxMBeanServer.java:225)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.(JmxMBeanServer.java:170)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.newMBeanServer(JmxMBeanServer.java:1401)
        at javax.management.MBeanServerBuilder.newMBeanServer(MBeanServerBuilder.java:93)
        at javax.management.MBeanServerFactory.newMBeanServer(MBeanServerFactory.java:311)
        at javax.management.MBeanServerFactory.createMBeanServer(MBeanServerFactory.java:214)
        at javax.management.MBeanServerFactory.createMBeanServer(MBeanServerFactory.java:175)
        at sun.management.ManagementFactory.createPlatformMBeanServer(ManagementFactory.java:302)
        at java.lang.management.ManagementFactory.getPlatformMBeanServer(ManagementFactory.java:504)
        at org.apache.catalina.startup.Bootstrap.createClassLoader(Bootstrap.java:183)
        at org.apache.catalina.startup.Bootstrap.initClassLoaders(Bootstrap.java:92)
        at org.apache.catalina.startup.Bootstrap.init(Bootstrap.java:207)
        at org.apache.catalina.startup.Bootstrap.init(Bootstrap.java:275)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

That rings a bell. We need to run headless! To customize MacPort's Tomcat, edit setenv.local:

# sudo vi /opt/local/share/java/tomcat6/conf/setenv.local

This example is to use JDK1.7 and some self-signed certificate magic [setenv.local]

JAVA_JVM_VERSION=1.7
JAVA_OPTS="-Djava.awt.headless=true -XX:PermSize=500m -XX:MaxPermSize=800m -Xmx2g -Djavax.net.ssl.keyStore=/Users/doma/.keystore -Djavax.net.ssl.keyStorePassword=password -Djavax.net.ssl.trustStore=/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/jre/lib/security/cacerts -Djavax.net.ssl.trustStorePassword=changeit"

Restart Tomcat6:

sudo port unload tomcat6
sudo port load tomcat6

Did we fix it?

# sudo less /opt/local/share/java/tomcat6/logs/catalina.err
Jun 17, 2015 9:29:37 PM org.apache.catalina.core.AprLifecycleListener init
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: .:/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java
Jun 17, 2015 9:29:37 PM org.apache.coyote.http11.Http11Protocol init
INFO: Initializing Coyote HTTP/1.1 on http-8080
Jun 17, 2015 9:29:37 PM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 507 ms
Jun 17, 2015 9:29:37 PM org.apache.catalina.core.StandardService start
INFO: Starting service Catalina
Jun 17, 2015 9:29:37 PM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/6.0.35
Jun 17, 2015 9:29:37 PM org.apache.catalina.startup.HostConfig deployDescriptor
INFO: Deploying configuration descriptor host-manager.xml
Jun 17, 2015 9:29:38 PM org.apache.catalina.startup.HostConfig deployDescriptor
INFO: Deploying configuration descriptor manager.xml
Jun 17, 2015 9:29:38 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory docs
Jun 17, 2015 9:29:38 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory examples
Jun 17, 2015 9:29:38 PM org.apache.catalina.core.ApplicationContext log
INFO: ContextListener: contextInitialized()
Jun 17, 2015 9:29:38 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: contextInitialized()
Jun 17, 2015 9:29:38 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory ROOT
Jun 17, 2015 9:29:38 PM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Jun 17, 2015 9:29:38 PM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /0.0.0.0:8009
Jun 17, 2015 9:29:38 PM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/18  config=null
Jun 17, 2015 9:29:38 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 710 ms

Et voila. Tomcat started.

Background

The same process can be applied to downgrade anything in the ports tree. To find the proper release, see https://trac.macports.org/log/trunk/dports/devel/apache-ant

To see which versions you are currently having:

# sudo port installed apache-ant
The following ports are currently installed:
  apache-ant @1.8.4_0 (active)
  apache-ant @1.9.4_0

To use 1.9.4 again:

# sudo port activate apache-ant @1.9.4_0
--->  Deactivating apache-ant @1.8.4_0
--->  Cleaning apache-ant
--->  Activating apache-ant @1.9.4_0
--->  Cleaning apache-ant
# ant -version
Apache Ant(TM) version 1.9.4 compiled on April 29 2014

Reference: https://trac.macports.org/wiki/howto/InstallingOlderPort

6/01/2015

IntelliJ IDEA: pass JAVA_HOME, M2_HOME, MAVEN_OPTS to the IDE using Yosemite

Place the following content (enhance it to your taste obviously) to /Library/LaunchDaemons/setenv.MAVEN_OPTS.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
  <dict>
  <key>Label</key>
  <string>setenv.BAR</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/launchctl</string>
    <string>setenv</string>
    <string>MAVEN_OPTS</string>
    <string>-XX:PermSize=500m -XX:MaxPermSize=800m -Xmx2g -Djavax.net.ssl.keyStore=/Users/doma/.keystore -Djavax.net.ssl.keyStorePassword=password -Djavax.net.ssl.trustStore=/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/jre/lib/security/cacerts -Djavax.net.ssl.trustStorePassword=changeit</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>ServiceIPC</key>
  <false/>
</dict>
</plist>

You'll have to either restart your computer or run the following line to apply the changes:

launchctl load -w /Library/LaunchDaemons/setenv.MAVEN_OPTS.plist

The next candidate is M2_HOME, the file to create is /Library/LaunchDaemons/setenv.M2_HOME.plist :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
  <dict>
  <key>Label</key>
  <string>setenv.BAR</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/launchctl</string>
    <string>setenv</string>
    <string>M2_HOME</string>
    <string>/opt/local/share/java/apache-maven-3.1.1</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>ServiceIPC</key>
  <false/>
</dict>
</plist>

Again, restart or run the following to apply:

launchctl load -w /Library/LaunchDaemons/setenv.M2_HOME.plist

...and here's the proof that you don't have to set the value of the M2_HOME after each Maven project import:

Reference: http://www.dowdandassociates.com/blog/content/howto-set-an-environment-variable-in-mac-os-x-launchd-plist/


5/17/2015

Migrating SVN repositories to GIT

mkdir ~/mig
cd ~/mig
rm -rf parent
git svn clone file:///var/svn/repos/parent --stdlayout --no-metadata
cd parent
mv .git/refs/remotes/trunk .git/refs/heads
mv .git/refs/remotes/tags .git/refs/tags

git remote add origin git@java-notes.com:parent.git
git push origin --all

3/24/2015

FreeBSD: Consult installed ports' package message to see their requirements after installation

At installation time, ports display their pkg message to warn the user of further configuration. If for any reason you missed it (or just want to be sure you've done all the changes required for your system), you can display the messages for all ports:
pkg info -D -x `pkg query %n` | less
Excerpt of the results:
...
baobab-3.14.1:
bash-4.3.33:
======================================================================

bash requires fdescfs(5) mounted on /dev/fd

If you have not done it yet, please do the following:

        mount -t fdescfs fdesc /dev/fd

To make it permanent, you need the following lines in /etc/fstab:

        fdesc   /dev/fd         fdescfs         rw      0       0

======================================================================
bdftopcf-1.0.4:
bigreqsproto-1.1.2:
binutils-2.25:
bison-2.7.1,1:
...
Here's how to see how many ports you have installed:
pkg info | wc -l
Enjoy!

3/09/2015

IntelliJ Idea live templates: code for singletons

Say you have this class:

public class TerminalTitlebar {
    public void set(String title) {
        System.out.println("\033]0;" + title + "\007");
    }
}

...and you want to introduce code to change this into a singleton easily.

File -> Settings -> Live Templates -> Click + to create a new entry.

Enter i for abbreviation, "singleton instance" or something similar for description, and the code in the "Template text" field:

private static $CLASS_NAME$ instance;
public static $CLASS_NAME$ getInstance() {
    return instance == null ? instance = new $CLASS_NAME$() : instance;
}

Now click "Edit Variables", and change the Expression for CLASS_NAME to "className()", press OK

To tell IntelliJ to use the generated snippet in Java code, click "Change" in the "Applicable in" line, and select Java.

Now type the letter i (this was the abbreviation we used earlier) and press TAB and the magic happens:

public class TerminalTitlebar {
    private static TerminalTitlebar instance;

    public static TerminalTitlebar getInstance() {
        return instance == null ? instance = new TerminalTitlebar() : instance;
    }

    public void set(String title) {
        System.out.println("\033]0;" + title + "\007");
    }
}

Voila, you can use it in any class. Enjoy!


1/19/2015

Automatic logger generation using IntelliJ Idea's Live Templates (use it with log4j, slf4j, commons-logging, etc by changing the template line accordingly)

In IntelliJ Idea, go to File -> Settings -> Live Templates, and click the + sign. Fill in the details:

  • Abbreviation: log
  • Description: log
  • Check "Reformat according to style" will indent the generated line appropriately.
  • Checking "Shorten FQ names" will remove "org.apache.log4j." and replace it with an import.

"Template text" is

private static final org.apache.log4j.Logger LOGGER = org.apache.log4j.Logger.getLogger($CLASS_NAME$.class);

The same for slf4j is

private final static Logger log = org.slf4j.LoggerFactory.getLogger($CLASS_NAME$.class);

Now click "Edit Variables", and in the CLASS_NAME row, enter className() in the Expression column.

Almost done - we still need to tell IDEA that we need this for Java stuff. Where it says "No applicable contexts", click "Define" - click JAVA, and OK.

Open any of your classes, and into a newline under "public class Blah", type "log" and press tab - and the logger line will be created appropriately:

private static final Logger LOGGER = Logger.getLogger(HSQLSequenceGenerator.class);

9/29/2014

Using gcc48 to build ports on FreeBSD

cd /usr/ports/devel/binutils && make install
cd /usr/ports/lang/gcc48 && make install
Add this to /etc/make.conf:

.if !empty(.CURDIR:M/usr/ports/*) && exists(/usr/local/bin/gcc48)
.if empty(.CURDIR:M/usr/ports/net/openldap*) && empty(.CURDIR:M/usr/ports/xxx/yyy)
CC=gcc48
CXX=g++48
CPP=cpp48
CFLAGS+=-Ofast -fno-strict-aliasing -pipe  
CPUTYPE=corei7
.endif
.endif

Edit /etc/libmap.conf:
libgcc_s.so.1   gcc48/libgcc_s.so.1
libgomp.so.1    gcc48/libgomp.so.1
libobjc.so.3    gcc48/libobjc.so.2
libssp.so.0     gcc48/libssp.so.0
libstdc++.so.6  gcc48/libstdc++.so.6

References:
https://www.freebsd.org/doc/en/articles/custom-gcc/article.html

9/18/2014

Building and installing Apache Maven 3.0.5 from sources


cd ~/tools
wget http://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.0.5/apache-maven-3.0.5-src.tar.gz
tar xvzf apache-maven-3.0.5-src.tar.gz
cd apache-maven-3.0.5
#for the next line to succeed, you need a binary maven version in the path
mvn clean install -DskipTests
cd ..
tar xvzf apache-maven-3.0.5/apache-maven/target/apache-maven-3.0.5-bin.tar.gz

9/10/2014

Regenerate hinting for all fonts

First you have to install TTF Autohinter.
sudo apt-get install libtool automake autoconf qt4-qmake automoc imagemagick inkscape pandoc help2man
cd ~/tools
git clone http://repo.or.cz/ttfautohint.git
cd ttfautohint/
./bootstrap
./configure --with-doc=no
make
make install
Under Ubuntu 12.04, you will need to download and compile harfbuzz:
wget http://www.freedesktop.org/software/harfbuzz/release/harfbuzz-0.9.26.tar.bz2
tar xf harfbuzz-0.9.26.tar.bz2
cd harfbuzz-0.9.26
./configure && make && sudo make install
sudo ldconfig
Under later versions you may try sooner or later
sudo apt-get install harfbuzz
Then it's so simple:
mkdir -p ~/.fonts
for file in $(find /usr -name '*.ttf'); do ttfautohint -c -d -i --hinting-range-min=6 -i $file ~/.fonts/${file##*/}; done
fc-cache -fv

9/09/2014

Installing Nexus OSS from sources

After all it's not that tricky. Build fails with Maven 3.0.x, make sure to use a later version, 3.2.3 seems to be working fine. You'll also need the http.ssl hacks.

Pre-requisities

You'll need git. Using Ubuntu/Debian, a
sudo apt-get install git
will do, or on FreeBSD you can use
sudo portmaster devel/git
And now the fun part. On FreeBSD, the lines involving maven can be omitted if a version is already installed via ports via a "sudo portmaster devel/maven3"
cd ~/tools
wget http://apache.cu.be/maven/maven-3/3.2.3/binaries/apache-maven-3.2.3-bin.tar.gz
tar xvzf apache-maven-3.2.3-bin.tar.gz
ln -s ~/tools/apache-maven-3.2.3 ~/tools/maven
export PATH=~/tools/maven/bin:$PATH

export MAVEN_OPTS="-XX:PermSize=1500m -XX:MaxPermSize=1800m -Xmx4g"
cd ~/dev
git clone https://github.com/sonatype/nexus-oss.git
cd nexus-oss

# if you don't need https just uncomment below 
cat >> etc/org.sonatype.nexus.cfg << FILE_SEPARATOR
application-port-ssl=8443
FILE_SEPARATOR

mvn -Dskip-testsuite -DskipTests -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true
sudo unzip -d /opt assemblies/nexus-base-template/target/nexus-base-template-*.zip
sudo ln -s /opt/nexus-base-template-* /opt/nexus

Autostart on Ubuntu/Debian

As of today, the wrapper service we can use in Karaf to autostart things does not work. As a workaround to autostart, create a /etc/init.d/nexus file:
#!/bin/bash

NEXUS_HOME=/opt/nexus

case "$1" in
  start)
    log_begin_msg "Starting Nexus OSS..."
        $NEXUS_HOME/bin/start
    log_end_msg 0
    ;;
  stop)
    log_begin_msg "Shutting down Nexus OSS..."
        $NEXUS_HOME/bin/stop
    log_end_msg 0
    ;;
  *)
  ;;
esac
...and execute this statement:
sudo update-rc.d nexus defaults 98 02

Autostart on FreeBSD

Start by putting the following script to /etc/rc.d/nexus:
#!/bin/sh

. /etc/rc.subr

name="nexus"
start_cmd="\${name}_start"
stop_cmd="\${name}_stop"
export NEXUS_HOME=/opt/nexus
export JAVA_HOME=/usr/local/openjdk7

nexus_start() {
        \$NEXUS_HOME/bin/start
}

nexus_stop() {
        \$NEXUS_HOME/bin/stop
}

load_rc_config \${name}
run_rc_command "\$1"
...and adapt appropriately to your system of course. You'll need to make it executable:
chmod +x /etc/rc.d/nexus

To activate it, you need to add the following to your /etc/rc.conf:
nexus_enable="YES"

If you need this often

If you need to re-do the same thing from time to time in different environments for different projects, you prefer to simplify things. So here is the single-copy-paste-prepared version; the same as above, this time without the explanation, automated.

cat > /etc/rc.d/nexus << FILE_SEPARATOR
#!/bin/sh

. /etc/rc.subr

name="nexus"
start_cmd="\${name}_start"
stop_cmd="\${name}_stop"
export NEXUS_HOME=/opt/nexus
export JAVA_HOME=/usr/local/openjdk7

nexus_start() {
        \$NEXUS_HOME/bin/start
}

nexus_stop() {
        \$NEXUS_HOME/bin/stop
}

load_rc_config \${name}
run_rc_command "\$1"
FILE_SEPARATOR
chmod +x /etc/rc.d/nexus

cat >> /etc/rc.conf << FILE_SEPARATOR
nexus_enable="YES"
FILE_SEPARATOR

service nexus start

Usage

To deploy to the locally installed Nexus, you can
  • - change your pom.xmls to refer to this local nexus for deployment
  • - change your settings.xml use the local nexus for deployment
  • <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                              http://maven.apache.org/xsd/settings-1.0.0.xsd">
    
       <mirrors>
            <mirror>
                <id>nexus</id>
                <name>nexus</name>
                <mirrorOf>external:*</mirrorOf>
                <url>http://127.0.0.1:8081/content/groups/public/</url>
            </mirror>
        </mirrors>
    
        <servers>
            <server>
                <id>jnc</id>
                <username>tomcat</username>
                <privateKey>${user.home}/.ssh/id_rsa</privateKey>
            </server>
            <server>
                <id>nexus</id>
                <username>admin</username>
                <password>{Oen5wNM4lygHMZ9vf+6T5qmsePRcQbWtrc2AWkTrpKg=}</password>
            </server>
            <server>
                <id>snapshots</id>
                <username>admin</username>
                <password>{Oen5wNM4lygHMZ9vf+6T5qmsePRcQbWtrc2AWkTrpKg=}</password>
            </server>
            <server>
                <id>releases</id>
                <username>admin</username>
                <password>{Oen5wNM4lygHMZ9vf+6T5qmsePRcQbWtrc2AWkTrpKg=}</password>
            </server>
        </servers>
    
        <profiles>
            <profile>
                <id>local</id>
                <activation>
                    <activeByDefault>true</activeByDefault>
                </activation>
                <properties>
        <nexus.url>http://127.0.0.1:8081</nexus.url>
                    <repos.public.url>${nexus.url}/content/groups/public</repos.public.url>
                    <repos.release.url>${nexus.url}/content/repositories/releases</repos.release.url>
                    <repos.snapshot.url>${nexus.url}/content/repositories/snapshots</repos.snapshot.url>
                </properties>
                <repositories>
                    <repository>
                        <id>nexus</id>
                        <name>public</name>
                        <url>${repos.public.url}</url>
                        <layout>default</layout>
                        <snapshots>
                            <enabled>true</enabled>
                            <updatePolicy>always</updatePolicy>
                        </snapshots>
                        <releases>
                            <enabled>true</enabled>
                            <updatePolicy>daily</updatePolicy>
                        </releases>
                    </repository>
                    <repository>
                        <id>snapshots</id>
                        <name>snapshots</name>
                        <url>${repos.snapshot.url}</url>
                        <layout>default</layout>
                        <snapshots>
                            <enabled>true</enabled>
                            <updatePolicy>always</updatePolicy>
                        </snapshots>
                        <releases>
                            <enabled>false</enabled>
                            <updatePolicy>daily</updatePolicy>
                        </releases>
                    </repository>
                    <repository>
                        <id>releases</id>
                        <name>releases</name>
                        <url>${repos.release.url}</url>
                        <layout>default</layout>
                        <snapshots>
                            <enabled>false</enabled>
                        </snapshots>
                        <releases>
                            <enabled>true</enabled>
                            <updatePolicy>daily</updatePolicy>
                        </releases>
                    </repository>
                </repositories>
    
                <pluginRepositories>
                    <pluginRepository>
                        <id>nexus</id>
                        <name>public</name>
                        <url>${repos.public.url}</url>
                        <layout>default</layout>
                        <snapshots>
                            <enabled>true</enabled>
                            <updatePolicy>always</updatePolicy>
                        </snapshots>
                        <releases>
                            <enabled>true</enabled>
                            <updatePolicy>daily</updatePolicy>
                        </releases>
                    </pluginRepository>
                    <pluginRepository>
                        <id>snapshots</id>
                        <name>snapshots</name>
                        <url>${repos.snapshot.url}</url>
                        <layout>default</layout>
                        <snapshots>
                            <enabled>true</enabled>
                            <updatePolicy>always</updatePolicy>
                        </snapshots>
                        <releases>
                            <enabled>false</enabled>
                            <updatePolicy>daily</updatePolicy>
                        </releases>
                    </pluginRepository>
                    <pluginRepository>
                        <id>releases</id>
                        <name>releases</name>
                        <url>${repos.release.url}</url>
                        <layout>default</layout>
                        <snapshots>
                            <enabled>false</enabled>
                        </snapshots>
                        <releases>
                            <enabled>true</enabled>
                            <updatePolicy>daily</updatePolicy>
                        </releases>
                    </pluginRepository>
                </pluginRepositories>
            </profile>
        </profiles>
    </settings>
    
    
    ...and this goes to settings-security.xml, using the default password for authentication. If following this guide, on your local, firewalled server the default username/password combination might do. Otherwise change your password in nexus and update your settings.xml and settings-security.xml appropriately as described here.
    <settingsSecurity>
      <master>{KFp2s9kTyrcHsy+BT4dooaLri1eMcy+32raBPgydYvw=}</master>
    </settingsSecurity>
    
  • - use the following construct which overrides your default deployment directory:
    mvn clean deploy -DaltDeploymentRepository=nexus::default::http://127.0.0.1:8081/content/repositories/snapshots
    

Possible errors

Using Maven versions earlier than 3.2.3 may yield to the following error:
Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty