Tuesday, April 19, 2016

Jenkins slave's environment variables on Ubuntu

I failed to set environment variables on a Jenkins slave running ssh on Ubuntu.
Adding EXPORT's to ~/.bashrc didn't work even though it works for interactive logging-in.
Creating ~/.pam_environment and adding environment variables successfully sets them even though it doesn't work for interactive logging-in.
So, I use both ~/.pam_environment and ~/.bashrc.

Tuesday, March 22, 2016

Make Git Extensions run GitK with the most recent Git for Windows

If you are using the 2.48.05 version of Git Extensions and have changed the git command to the most recent 64 bit version of Git for Windows from the Internet, the main menu item GitK under Tools doesn't work anymore. You can fix it as follows.
  1. Go to the folder "C:\Program Files\Git\cmd"
  2. Create a text file named "gitk.cmd"
  3. Copy and paste the following code into it.
    @cd %~dp0
    @start "" gitk.exe %*
    
Now you can run GitK from the menu item Tools/GitK.

Wednesday, February 24, 2016

Lettuce throws NoSuchMethodError at Spring Data Redis and Spring Session

I use NetBenas 8.0.2 and the bundled default web server GlassFish to make a web service. I decided to use Lettuce 3.4.1 to connect from my web service to Redis 3.0 for managing sessions. I use Spring Data Redis 1.6.4 and Spring Session 1.0.2, and set them up in "WEB-INF\applicationContext.xml" as following.
<bean class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"
p:host-name="localhost"/>
When I started the web service, I got the following exception at the start-up.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory#0' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: com.google.common.collect.Sets.newConcurrentHashSet()Ljava/util/Set;
The cause of this exception java.lang.NoSuchMethodError is that GlassFish has loaded its own old Guava 1.3 of C:\Program Files\glassfish-4.1\glassfish\modules\guava.jar instead of the web application's packaged recent Guava 1.8 and Lettuce tries to call the new method newConcurrentHashSet() since Guava 1.5, which doesn't exist in Guava 1.3 installed with GlassFish.
I fixed this problem by adding a new file, "WEB-INF/glassfish-web.xml" with the next content,
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD 
GlassFish Application Server 3.1 Servlet 3.0//EN" 
"http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app>
    <class-loader delegate="false"/>
</glassfish-web-app>
This enables you to load your own packaged jars first before GlassFish loads its own jars.

Tuesday, February 16, 2016

Enable Broadcom BCM57780 after installing Ubuntu Server 14.04.2

When you install Ubuntu Server 14.04.2 on Dell Vostro 430, the ethernet interface is not recognized in the phase of "Detect network hardware" with the following message.
[!] Configure the network
No network interfaces detected
No network interfaces were found. The installation system was unable to find a network
device.
You may need to load a specific module for you network card, if you have one. For this,
go back to the network hardware detection step.
The unrecognized ethernet interface on my Dell Vostro 430 is Broadcom Corporation NetLink BCM57780 Gigabit Ethernet. Despite this, just keep installing even though the network is disabled when the installation completes.
After the installation, log in to the system on the console with the physical keyboard and type in the next command to list all the network interfaces.
$ ifconfig -a
The option -a shows all the network interfaces even though some of them are disabled. This command prints on the console as following.
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:32 errors:0 dropped:0 overruns:0 frame:0
          TX packets:32 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:2480 (2.4 KB)  TX bytes:2480 (2.4 KB)

p128p1    Link encap:Ethernet  HWaddr a4:ba:db:01:9d:f6
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
          Interrupt:16
The disabled ethernet interface is p128p1. Memorize it to type in while configuring the network.
Start editing /etc/network/interfaces with the next command using vi.
$ sudo vi /etc/network/interfaces
Add the last two green lines to the file as follows.
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

auto p128p1
iface p128p1 inet dhcp
Reboot the system with the following command.
$ sudo reboot
Now the system is connected to the network.

Sunday, January 31, 2016

Install Ansible on Windows with Cygwin

  1. Install Cygwin with all the items under the categories Devel, Python, plus openssh and wget 

    At the step of "Select Packages", toggle the categories Devel, Python from "Default" to "Install" which selects all the items under the category, and toggle openssh under "Net" and wget under "Web" from "Skip" to each version. Ignore any "Setup Alert" message boxes which say that you should install something else by yourself.
  2. Create Ansible.bat

    You may have Windows-native Python installed on your Windows. In order to prevent it from interfering with Cygwin's python, write the following batch script that clears the Windows PATH. Run this Ansible.bat to enter the sandboxed Ansible environment.
    @path ;
    @C:\cygwin64\Cygwin.bat
    
  3. Install PIP and Ansible through PIP

    At the bash prompt of Ansible.bat, enter the following commands
    $ easy_install-2.7 pip
    $ pip install ansible
    
  4. Add Ansible variables to .bashrc

    Edit ~/.bashrc by adding the following environment variables used by Ansible
    # Ansible settings
    export ANSIBLE_SCP_IF_SSH=y
    export ANSIBLE_SSH_ARGS='-o ControlMaster=no'
    
  5. Install sshpass

    In order to enable Ansible options --ask-pass, --ask-become-pass, you need to install sshpass by yourself. Run the following commands
    $ wget http://downloads.sourceforge.net/project/sshpass/sshpass/1.05/sshpass-1.05.tar.gz
    $ tar -xvf sshpass-1.05.tar.gz
    $ cd sshpass-1.05
    $ ./configure
    $ make install
    
  6. Rerun Ansilbe.bat

    Close the previous Cygwin prompt that you have used for installing and run Ansible.bat again. Now you can run the following command to check if Ansible is installed.
    $ ansible --version
    
    Always run Ansible.bat to use Ansible commands.

Tuesday, January 19, 2016

Add resources from Resources.resx to XAML

You may have tried this technique gleaned from the Internet in order to change your WPF GUI's text at runtime according to the language.
When you write the next snippet in your Window's XAML for adding resources from the Resources.resx file and rebuild and run in Visual Studio 2015,

<Window
    ...
    xmlns:props="clr-namespace:MyProject.Properties" 
    >
    <Window.Resources>
        <props:Resources x:Key="LocalResources" />
    </Window.Resources>
    <Window.BindingGroup>
        <BindingGroup Name="localization"/>
    </Window.BindingGroup>
    <Window.Title>
        <Binding Path="WindowTitleStringName"
                 Source="{StaticResource LocalResources}"
                 BindingGroupName="localization"/>
    </Window.Title>
    <Label Content="{Binding LabelContentStringName,
                             Source={StaticResource LocalResources},
                             BindingGroupName=localization}"
        ...
       />
</Window>
// Change to the default Resources.resx in MyWindow.cs
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture ;
Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture ;
BindingGroup.BindingExpressions
    .Where( be => be.BindingGroup.Name=="localization" )
    .ToList().ForEach( be => be.UpdateTarget() );

the next exception is thrown.

System.Windows.Markup.XamlParseException / System.MissingMethodException :
    No matching constructor found on type MyProject.Properties.Resources.
    You can use the Arguments or FactoryMethod directives to construct this type.

If you slightly modify Resources.Designer.cs like adding meaningless spaces and just build(not rebuild) and run, the exception is not thrown any more.

Even so, this can be a problem when this app is built in an automated build system.

In order to solve this problem, derive your own Resources class from MyProject.Properties.Resources  and use it with the already defined "local" namespace in your xaml like the next.
namespace MyProject
{
    public class Resources 
        : Properties.Resources
    {
        public Resources()
        {
        }

    }  // End Of Class
}

<Window
    ...
    xmlns:props="clr-namespace:MyProject.Properties"
    >
    <Window.Resources>
         <local:Resources x:Key="LocalResources" />
    </Window.Resources>
    ...
</Window>

Tuesday, March 24, 2015

Spring REST and wildcard url-pattern in web.xml

The wildcard url-pattern '/api/*' in web.xml doesn't work with Spring REST @RequestMapping's absolute path like '/api/customers'.
@RequestMapping's relative path without any leading slash like 'customers' does work.

In web.xml
  <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/api/*</url-pattern>
    <url-pattern>*.htm</url-pattern>
  </servlet-mapping>

In your java source code
 @RequestMapping( "customers" )

Now you can use the URL 'http://myserver.com/api/customers'.