tl;dr

In a previous article I wrote about installing and using the Salesforce Data Loader command line tools on Linux. This article expands on fixing the graphical tooling as well.

Salesforce Data Loader – a.k.a. Apex Data Loader – is a tool for bulk import and export of data into applications running on the Salesforce platform. Salesforce says it’s Windows and MacOS only. Do not believe the vendor. You can use it on Linux without trouble: command line utils as well as the graphical frontend.

Disclaimer: I rarely use frontends

When writing my first article, I just focused on using the command line tools. They were the only interesting part for me. I needed them in a concrete project, where we helped a customer to get rid of a commercial integration software. Linux was the target platform for batch import jobs back then.

I failed to see that many other people out there want to use the graphical tooling on Linux as well. Thanks for my readers for pointing that out! In this article I want to fill this gap and provide instructions how to use the graphical tooling.

The symptoms: Native library calls fail

Our starting point is the uber jar extracted from the Salesforce package. You should have it as a result of following my first article.

When trying to run the jar on linux anyways, we get a confusing error message:

$ /usr/lib/jvm/java-8-openjdk-amd64/bin/java -cp dataloader-38.0.1-uber.jar com.salesforce.dataloader.process.DataLoaderRunner
...
Exception in thread "main" java.lang.UnsatisfiedLinkError: Cannot load 32-bit SWT libraries on 64-bit JVM
	at org.eclipse.swt.internal.Library.loadLibrary(Unknown Source)
	at org.eclipse.swt.internal.Library.loadLibrary(Unknown Source)
	at org.eclipse.swt.internal.C.<clinit>(Unknown Source)
	at org.eclipse.swt.widgets.Display.<clinit>(Unknown Source)
	at com.salesforce.dataloader.ui.LoaderWindow.<init>(LoaderWindow.java:89)
	at com.salesforce.dataloader.controller.Controller.createAndShowGUI(Controller.java:214)
	at com.salesforce.dataloader.process.DataLoaderRunner.main(DataLoaderRunner.java:45)

The message hints into the direction, that using Debian’s Multiarch features and running an i386 OpenJDK might heal the situation. Of course it doesn’t:

$ apt-get install openjdk-8-jdk:i386
...
$ /usr/lib/jvm/java-8-openjdk-i386/bin/java -cp dataloader-38.0.1-uber.jar com.salesforce.dataloader.process.DataLoaderRunner
...
Exception in thread "main" java.lang.UnsatisfiedLinkError: Could not load SWT library. Reasons: 
	no swt-win32-4528 in java.library.path
	no swt-win32 in java.library.path
	Can't load library: /home/vagrant/.swt/lib/linux/x86/libswt-win32-4528.so
	Can't load library: /home/vagrant/.swt/lib/linux/x86/libswt-win32.so

	at org.eclipse.swt.internal.Library.loadLibrary(Unknown Source)
	at org.eclipse.swt.internal.Library.loadLibrary(Unknown Source)
	at org.eclipse.swt.internal.C.<clinit>(Unknown Source)
	at org.eclipse.swt.widgets.Display.<clinit>(Unknown Source)
	at com.salesforce.dataloader.ui.LoaderWindow.<init>(LoaderWindow.java:89)
	at com.salesforce.dataloader.controller.Controller.createAndShowGUI(Controller.java:214)
	at com.salesforce.dataloader.process.DataLoaderRunner.main(DataLoaderRunner.java:45)

By now it should be getting obvious: Something is wrong with this jar.

Flaws of the Salesforce uber jar

Let’s inspect the uber jar:

$ jar tvf dataloader-38.0.1-uber.jar
...
 53248 Wed Aug 12 10:05:26 CEST 2015 swt-awt-win32-4528.dll
118784 Wed Aug 12 10:05:26 CEST 2015 swt-gdip-win32-4528.dll
 77824 Wed Aug 12 10:05:26 CEST 2015 swt-webkit-win32-4528.dll
 61440 Wed Aug 12 10:05:26 CEST 2015 swt-wgl-win32-4528.dll
438272 Wed Aug 12 10:05:26 CEST 2015 swt-win32-4528.dll
 77824 Wed Aug 12 10:05:26 CEST 2015 swt-xulrunner-win32-4528.dll
     0 Fri Sep 04 00:41:50 CEST 2015 org/eclipse/swt/
...
     0 Fri Sep 04 00:41:50 CEST 2015 org/eclipse/swt/internal/
     0 Fri Sep 04 00:41:48 CEST 2015 org/eclipse/swt/internal/gdip/
     0 Fri Sep 04 00:41:48 CEST 2015 org/eclipse/swt/internal/image/
     0 Fri Sep 04 00:41:48 CEST 2015 org/eclipse/swt/internal/mozilla/
     0 Fri Sep 04 00:41:48 CEST 2015 org/eclipse/swt/internal/mozilla/init/
     0 Fri Sep 04 00:41:44 CEST 2015 org/eclipse/swt/internal/ole/
     0 Fri Sep 04 00:41:48 CEST 2015 org/eclipse/swt/internal/ole/win32/
     0 Fri Sep 04 00:41:48 CEST 2015 org/eclipse/swt/internal/opengl/
     0 Fri Sep 04 00:41:48 CEST 2015 org/eclipse/swt/internal/opengl/win32/
     0 Fri Sep 04 00:41:48 CEST 2015 org/eclipse/swt/internal/theme/
     0 Fri Sep 04 00:41:48 CEST 2015 org/eclipse/swt/internal/webkit/
     0 Fri Sep 04 00:41:48 CEST 2015 org/eclipse/swt/internal/win32/
     0 Fri Sep 04 00:41:50 CEST 2015 org/eclipse/swt/layout/
     0 Fri Sep 04 00:41:46 CEST 2015 org/eclipse/swt/ole/
     0 Fri Sep 04 00:41:50 CEST 2015 org/eclipse/swt/ole/win32/
...

We notice some embedded org/eclipse/swt classes and the swt-*-win32-4528.dll native Windows library files. Obviously, Salesforce packaged a platform dependent SWT distribution into the uber jar. We need to replace it by a version that works on our platform.

The uber jar is shaded. Hence, all class files are stored flat in the uber jar instead of using embedded jars. Simple jar overloading is not an option. We have to do a little surgery.

Replacing the SWT library

We’ll demonstrate the process on an Ubuntu 18.04 distribution. In order to use SWT, we need to make sure that the proper system-provided java and jni native libraries are installed:

$ apt-get install libswt-gtk-4-java libswt-cairo-gtk-4-jni

Here is a step-by-step guide to patch the uber jar.

  1. create a temporary folder and extract the uber-jar into it
    .../Data Loader$ mkdir dataloader-temp
    .../Data Loader$ cd dataloader-temp
    .../Data Loader/dataloader-temp$ jar xf ../dataloader-38.0.1-uber.jar 
    
  1. remove the Windows version of org/eclipse/swt that Salesforce foisted on us
    .../Data Loader/dataloader-temp$ rm -rf org/eclipse/swt/
    
  1. place a proper version of SWT into the folder
    .../Data Loader/dataloader-temp$ jar xf /usr/share/java/org.eclipse.swt-4.x.jar org/eclipse/swt
    
  1. repackage the uber-jar with the updated content
    .../Data Loader/dataloader-temp$ jar cf ../dataloader-38.0.1-uber-patched.jar .
    
  1. go for a test drive.
    .../Data Loader/dataloader-temp$ cd ..
    .../Data Loader$ java -cp dataloader-38.0.1-uber-patched.jar com.salesforce.dataloader.process.DataLoaderRunner
    

Et voilà: You are presented with the GUI for Salesforce Data Loader.

Salesforce Data Loader GUI: Start screen

Applying to other Linuxen

The recipe in this article only applies to Ubuntu. However, it is easy to transfer to other Linuxen.

  1. Install an OpenJDK 8 + SWT libraries using your package manager.
  2. Find the location of the swt jar.
  3. Patch the included org/eclipse/swt classpath inside the Salesforce Data Loader uber jar with your system SWT.
  4. Repackage.

Have fun with your patched Salesforce Data Loader!

metamorphant and Salesforce

Why did we write this article in the first place? We think our customers can benefit from it and breach arbitrary, vendor-defined frontiers.

At metamorphant we are no Salesforce experts, but we are committed to liberating enterprises. With our broad skillset in processes and technologies, we support our customers through a product’s whole lifecycle inside the enterprise. That distinguishes us from other (mostly big) consultancies who focus on the journey that follows immediately after the introduction of a new product. They reap the quick wins and do what money-driven mercenaries do: run away when things get serious. Of course, they’ll keep the bonus that you paid them in advance for their quick successes.

Ideally, a product’s lifecycle is

from birth
to success
to more success
to death

and not

from birth
to success
to bare subsistence as creeping living dead.

After some expansion and specialization, a customer will outgrow any solution. It is a sign of a healthy sustained gain. Of course, in the case of unforeseen failure, the ability to kill components quickly is even more important.

If you don’t want your successful products to end as undead zombies, you better take care.



Post header background image by Free-Photos from Pixabay.


Contact us