Here a a few steps to use LimeWire's classes to enable BitTorrent downloading from your Java program.

  1. Download LimeWire for Other Systems (OS/2, Solaris, Linux)
  2. Unzip the downloaded file. You'll need the LimeWire.jar file (obviously) but also the ones for commons-logging, guice, httpclient, httpcore and httpcore-nio. Depending on further developments and more advanced uses of the API, you might need more but it will be easy to guess with trial and error.
  3. Time to start coding. I'll only write code snippets here and will let you make your own architecture around it.
    First, we'll configure the default save path. Note that this is the path for completed files. LimeWire will automatically create a directory at the same level for incomplete files. So, if you set /tmp as save path, it will try to create /tmp/Incomplete. Being the default path, this should only be done once (e.g. in a static initialization method).
    SharingSettings.setSaveDirectory(new File("/tmp/limewire_test/Complete"));
  4. Onwards with the download itself. We now need to load the .torrent file. The API says there is a method to load directly from a file but it wouldn't compile with my version of the binaries so I used a byte array :
    Injector injector = Guice.createInjector(Stage.PRODUCTION, new LimeWireCoreModule(ActivityCallbackAdapter.class));
    BTMetaInfo metaInfo = injector.getInstance(BTMetaInfoFactory.class).createBTMetaInfoFromBytes(FileUtils.readFileFully(torrentFile));
  5. Then, we create the downloader...
    CoreDownloaderFactory coreDownloaderFactory = injector.getInstance(CoreDownloaderFactory.class);
    BTDownloader downloader = coreDownloaderFactory.createBTDownloader(metaInfo);
  6. ... and set its save path
    // Note: due to a bug, passing null as second parameter does not act as the default file.
    // Passing the value that was used before setting the save file works, though
    downloader.setSaveFile(null, downloader.getSaveFile().getAbsolutePath(), false);
  7. We can then start the download.
  8. Monitoring the download can be done in at least two non-exclusive ways:
    1. Check downloader.getState() periodically and report progress in an interface
    2. Listen for events using downloader.addListener(EventListener<downloadsatusevent>)
    Which way is better depends on what you're trying to achieve.

If you wish to add more features, you can read the API documentation for LimeWire.

For those who still remember why I tried to use LimeWire in the first place, it turns out I'm still "stuck" with Azureus. Indeed, we need a tracker and Azureus seems to be the only maintained program or library to offer one (even though I'm not following the Azureus releases because it's a pain to upgrade even to minor releases).