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'.

Sunday, December 7, 2014

Gitblit with Active Directory

[ERROR] Error Connecting to LDAP
LDAPException(resultCode=49 (invalid credentials), errorMessage='80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1 ', diagnosticMessage='80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1 ')
This could be the wrong password.
So I tested with my personal Active Directory account and it worked.
realm.authenticationProviders = ldap
realm.ldap.server = ldap://192.168.0.2
realm.ldap.username = [DOMAINNAME]\\duncansungwkim
realm.ldap.password = [YourPassword]
realm.ldap.accountBase = CN=Users,DC=[domainname],DC=[your-org],DC=com
Any Active Directory account in the "Domain Users" group will work.
In fact, you should ask your Active Directory administrator for the password of a special account that is only for anthentication. That account should be only in the "Domain Users" group, which I believe has the least rights.

Tuesday, April 1, 2014

Workaround of git Shallow Clone with Submodules

You can clone a git repo only with the most recent revision by using git's "shallow clone" as the following
command.
$ git clone --depth 1 https://github.com/MyRepo.git

If you have submodules, you would use the option --recursive as follows
$ git clone --depth 1 --recursive https://github.com/MyRepo.git
And you would expect that the submodules are also shallowly cloned, but they are actually full clones.

You can work around this problem by using consecutive commands in one line like the next
$ git clone --depth 1 https://github.com/MyRepo.git ; cd MyRepo ; git submodule update --init --depth 1
If you use Windows, use &(ampersand) instead of ; (semicolon).
C:\> git clone --depth 1 https://github.com/MyRepo.git & cd MyRepo & git submodule update --init --depth 1
This is such a primitive solution. However, this was really a good tip for using git for build automation.

One of my build jobs kept failing with the following error message.
error: RPC failed; result=56, HTTP code = 200
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed

It is said that this problem is caused by too big a git repo, maybe with over 20MB. I had big submodules but they were big due to its history. So I thought of the shallow clone, but it didn't work because git doesn't propagate the depth setting to the submodules when I use --recursive option. I couldn't wait for a new git version to fix this. Now I divided and conquered it.