Category: Build

Jenkins and the mysterious Accept timed out error

Not so long ago I’ve been trying to set up a new Jenkins job on a freshly created Jenkins slave. Unfortunately for me the first attempt of running the Maven build resulted in a failure:

ERROR: Aborted Maven execution for InterruptedIOException
java.net.SocketTimeoutException: Accept timed out
 at java.net.PlainSocketImpl.socketAccept(Native Method)
 at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398)
 at java.net.ServerSocket.implAccept(ServerSocket.java:530)
 at java.net.ServerSocket.accept(ServerSocket.java:498)
 at hudson.maven.AbstractMavenProcessFactory$SocketHandler$AcceptorImpl.accept(AbstractMavenProcessFactory.java:211)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:606)
 at hudson.remoting.RemoteInvocationHandler$RPCRequest.perform(RemoteInvocationHandler.java:309)
 at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:290)
 at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:249)
 at hudson.remoting.UserRequest.perform(UserRequest.java:118)
 at hudson.remoting.UserRequest.perform(UserRequest.java:48)
 at hudson.remoting.Request$2.run(Request.java:328)
 at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:72)
 at java.util.concurrent.FutureTask.run(FutureTask.java:262)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
 at java.lang.Thread.run(Thread.java:745)

Jenkins normally kicks off Maven builds by forking a Maven process on the system and then using Maven extensions to become part of the build process. So let’s have a look at an example command Jenkins runs for a Maven build:

[OpenAM] $ /jdk8/bin/java -cp /jenkins/maven31-agent.jar:/apache-maven-3.2.3/boot/plexus-classworlds-2.5.1.jar:/apache-maven-3.2.3/conf/logging jenkins.maven3.agent.Maven31Main /apache-maven-3.2.3 /jenkins/slave.jar /jenkins/maven31-interceptor.jar /jenkins/maven3-interceptor-commons.jar 57186

Here, that last parameter, 57186, looks quite suspiciously like a random port number. Could it be that Jenkins tries to connect to this local port and this connection fails resulting in the above stacktrace? Well, easy to test, let’s run the following iptables command on the box:

iptables -I INPUT -i lo -j ACCEPT

Try to rerun the build, and voilà, the build progresses further. Lesson learned. 😉

How to determine NSS/NSPR versions on Linux

Reverse engineering is a quite important skill to have when working with OpenAM, and this is even more the case for the web policy agents. Determining the version of the NSS and NSPR libraries may prove important when trying to build the agents, so here is a trick I’ve used in the past to determine the version of the bundled libraries.

To determine the version for NSPR, create nspr.c with the following content:

#include <dlfcn.h>
#include <stdio.h>

int main() {
        void* lib = dlopen("/opt/web_agents/apache24_agent/lib/libnspr4.so", RTLD_NOW);
        const char* (*func)() = dlsym(lib, "PR_GetVersion");
        printf("%sn", func());

        dlclose(lib);
        return 0;
}

Compile it using the following command (of course, make sure the path to the library is actually correct), then run the command:

$ gcc nspr.c -ldl
$ ./a.out
4.10.6

Here is the equivalent source for NSS, saved under nss.c:

#include <dlfcn.h>
#include <stdio.h>

int main() {
        void* lib = dlopen("/opt/web_agents/apache24_agent/lib/libnss3.so", RTLD_NOW);
        const char* (*func)() = dlsym(lib, "NSS_GetVersion");
        printf("%sn", func());

        dlclose(lib);
        return 0;
}

And an example output would look like:

$ gcc nss.c -ldl
$ ./a.out
3.16.3 Basic ECC

To determine the correct symbol names I’ve been using the following command:

nm -D libns{s,p}*.so | grep -i version

NOTE: While this code works nicely on Linux, for Windows and Solaris you will probably need a few adjustments, or there are potentially other/better ways to get information on the libraries.

How to compile 3.3.3 web agents on Linux

Trying to build the web policy agents may be a little frustrating at times, especially because it is generally not that well documented. As part of the 3.3.3 agent release I had the joy of going through the build process of the Linux web agents, so here you go, here are the steps I’ve gone through to build the agents on a freshly installed CentOS 5.10 (32 & 64 bit). For the very keen, I’ve also aggregated all the commands into shell scripts, you can find them at the bottom of this post.

Packages

On an out of the box CentOS 5.10 installation gcc is already installed, but there are some other components you should make sure you have installed before attempting to compile the agents:

  • subversion: To check out the source code of the agents.
  • ant: To perform the build, the agents are using Ant scripts to define the build steps.
  • zlib-devel: Compilation time dependency.
  • gcc-c++: C++ compiler.
  • rpm-build: RPM packages are being generated as part of the build process.
  • gcc44: Building NSS requires a newer GCC than the default one.
  • java-1.6.0-openjdk-devel: JDK to be able to build the agent installers (and run the Ant scripts).

The agent dependencies

The agents rely on the following external libraries:

  • NSS 3.16.3 & NSPR 4.10.6
    On 32 bit the component should be built with:

    make BUILD_OPT=1 NS_USE_GCC=1 NSS_ENABLE_ECC=1 NSDISTMODE="copy" CC="/usr/bin/gcc44 -Wl,-R,'$$ORIGIN/../lib' -Wl,-R,'$$ORIGIN'" nss_build_all

    On 64 bit the command is:

    make USE_64=1 BUILD_OPT=1 NS_USE_GCC=1 NSS_ENABLE_ECC=1 NSDISTMODE="copy" CC="/usr/bin/gcc44 -Wl,-R,'$$ORIGIN/../lib' -Wl,-R,'$$ORIGIN'" nss_build_all
  • PCRE 8.31
    On 32 bit:

    ./configure --with-pic --enable-newline-is-anycrlf --disable-cpp

    On 64 bit:

    CC="gcc -m64" CXX="g++ -m64" ./configure --with-pic --enable-newline-is-anycrlf --disable-cpp
  • libxml2 2.9.1
    On either platform:

    ./configure --prefix=/opt/libxml2 --with-threads --with-pic --without-iconv --without-python --without-readline
  • The header files of various web containers

Once all the libraries are in place, you can run the build on 32 bit:

ant nightly

on 64 bit:

ant nightly -Dbuild.type=64

And here are the shell scripts:
64-bit
32 bit

OpenDS 2.3.0 as embedded configstore in trunk

In the last few days the OpenAM trunk has been upgraded to use OpenDS 2.3 for embedded datastore, which is quite a big step from OpenDS 1.0. This change also affects the building process, so here are the changes, that you need to do to be able to build your OpenAM again:

  • Download OpenDS 2.3.0-build003
  • extract the zip to opensso/products/opends folder.
  • Copy the je.jar and OpenDS.jar from OpenDS-2.3.0-build003/lib folder into opensso/products/extlib directory (overriding the old ones).
  • Run the following command:
./create_opends_zip.sh OpenDS-2.3.0-build003
  • copy the resulted opends.zip also in the extlib folder.

And off you go, you can build your OpenAM now any way you want. 🙂