Hi,
This is just a quick post to consolidate my findings when investigating why a Null Pointer Exception occurs in SoapUI when running on Ubuntu. The error occurs in the analytics code when it tries to obtain the machine’s MAC address. For now, I have hopefully found a quick work around explained below.
I tested this when running SoapUI 5.2.1 (built & run from source code) on a clean install of Ubuntu 14.04.4, Java 1.7u79 and running on VirtualBox.
Problem Description
When starting you may see:
Aside from com.eviware.soapui.analytics.AnalyticsManager, a similar error can also be seen in com.eviware.soapui.analytics.providers.GoogleAnalyticsProvider.getMacAddressString when using different areas of functionality.
Looking at either of those classes where the NPE occurs we can see route cause is the same piece of code:
[code language=”java” gutter=”true” highlight=”1″]
NetworkInterface network = NetworkInterface.getByInetAddress(InetAddress.getLocalHost());
byte mac[] = network.getHardwareAddress();
MessageDigest hasher = MessageDigest.getInstance("SHA-1");
return createHexBinary(hasher.digest(mac));
[/code]
You can probably see that network is coming back as null.
Investigation
To understand why, and work around the problem, try running a snippet of the same code with logging added e.g. something like:
[code language=”java” gutter=”true”]
package com.company;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.security.MessageDigest;
public class Main {
public static void main(String[] args) {
try {
NetworkInterface network = NetworkInterface.getByInetAddress(InetAddress.getLocalHost());
System.out.println("Machine Name="+ InetAddress.getLocalHost());
System.out.println("Network Interface="+network);
byte mac[] = network.getHardwareAddress();
System.out.println("Mac Address="+mac);
MessageDigest hasher = MessageDigest.getInstance("SHA-1");
System.out.println("Hashed Mac"+hasher.digest(mac));
}
catch(Exception e){
System.out.println("Error generating Analytics session ID – returning empty String"+ e);
}
}
}
[/code]
Depending on how your hosts file / network settings are, you may see something like:
[code language=”bash” gutter=”false” highlight=”1″]
Machine Name=ubuntutest-VirtualBox/127.0.1.1
Network Interface=null
Error generating Analytics session ID – returning empty Stringjava.lang.NullPointerException
[/code]
The Machine Name will vary on your machine, but the Network Interface can be seen as null and a NullPointerException is caught. The problem seems to be that NetworkInterface.getByInetAddress cannot match the Machine Name to any of the Network Interface values. Running ifconfg shows that there is indeed no match available:
[code language=”bash” gutter=”false”]
ubuntutest@ubuntutest-VirtualBox:~$ ifconfig
eth0 Link encap:Ethernet HWaddr 07:07:27:79:d2:07
inet addr:10.0.2.30 Bcast:10.0.2.255 Mask:255.255.255.0
inet6 addr: fe80::a00:27ff:fe79:d101/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:21 errors:0 dropped:0 overruns:0 frame:0
TX packets:73 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3086 (3.0 KB) TX bytes:10810 (10.8 KB)
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:46 errors:0 dropped:0 overruns:0 frame:0
TX packets:46 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3559 (3.5 KB) TX bytes:3559 (3.5 KB)
[/code]
Work-Around
So without fixing the code, one quick solution is to change the /etc/hosts entry for your machine name to use the same IP address as eth0. So in my case, I did something like:
[code language=”bash” gutter=”false”]
sudo nano /etc/hosts
[/code]
And added:
[code language=”bash” gutter=”false”]
10.0.2.30 ubuntutest-VirtualBox
[/code]
Running the above snippet should then show the Network Interface correctly matched and the Mac Address found e.g.
[code language=”bash” gutter=”false”]
Machine Name=ubuntutest-VirtualBox/10.0.2.30
Network Interface=name:eth0 (eth0)
Mac Address=[B@520b368f
Hashed Mac[B@4a5e88f7
[/code]
Note – adding a host entry pointing to lo (127.0.0.1) solves the first problem of matching the Network Interface, but then fails when the code tries to obtain the MAC address with network.getHardwareAddress() – unlike eth0, the interface lo doesn’t have one!
Starting up SoapUI should now occur without the Analytics NPE.
Code Fix
Aside from having / changing your network settings to help the code work, it would probably be better to fix the code in SoapUI to iterate over the possible Network Interfaces until it finds one with a MAC address. I’ll maybe take more of a look at this later.
Comments
There are probably more or even better options for solving this problem, but I just wanted to get some options down in response to various SoapUI Community posts featuring this error for users running on Ubuntu. Hopefully this will help somewhat, please come in with any suggestions / corrections / comments!
Thanks,
Rup
Hi Rup,
I did notice these earlier, but ignored.
Will try you suggestion and let you know.
Thanks for the detailed investigation. I’m using Jenkins to run SoapUI on a linux VM (amazon hosted) and have the same issue.
Unfortunately soapui-settings.xml (UISettings@disable_analytics=true) seems to have no effect. Probably a bug …
Don’t know if I want to play with the hosts file, I guess I will live with the issue as it’s only a WARN message.
Weirdly, Jenkins can see the VM’s IP address no problemo
Hi, thanks for the comment, its useful feedback.
As you say, unfortunately the disable analytics option isn’t effective.
I think it is certainly a bug, or at least an opportunity to improve the code that selects the MAC address from the network interface and make it more robust.
Apart from changing the host file, its probably better to fix the code as part of the project. I might even be able to make a patch and package it as a jar file. Like you say it isn’t actually a serious issue, but its not great having stack traces etc.
Thanks,
Rup