I’ve been reasonably successful at getting JXTA to do a couple of simple but very helpful things. Herewith some remarks on where I’ve found it useful, and on the Absolute Minimum Necessary code to get a JXTA app running. [Update: James asks me to post the code, so here it is, with commentary, probably only of interest to JXTA-heads.]
JXTA is pretty big and pretty complicated, and its documentation is not that great. A couple of months in, I’m over the novice pain, but haven’t become one of the enthusiasts who think that if we swap out all our IP infrastructure and swap in JXTA, the world will be a better place.
JXTA has all these elaborate capabilities around pipes and abstract services and concrete services; I found them hard to understand and since they try really hard to avoid the Fallacies of Distributed Computing, they don’t sugar-coat much.
On the other hand, if you want a reliable, reasonably-simple way for a
bunch of processes in the network to discover each other dynamically—sort of
a friendly wrapper for multicast, if you will—in my experience JXTA is just the
ticket.
You set up a peer group, you join it, you add a
DiscoveryListener
, drop into a
DiscoveryService.getRemoteAdvertisements()
loop, and you’re
pretty well done.
It looks like the process can be
made very secure, too, although I haven’t worked through that part yet.
Anyhow, until fairly recently, getting a JXTA task started was kind of a pain, there was work to do in making sure you didn’t get port-number collisions, and there was this dorky “Configurator” program that popped up the first time you ran a JXTA app. Now there’s this ext:config thing, which is aimed at simplifying the process, and it seems to work pretty well.
What I wanted was to know the minimum amount of code that would get the
JXTA system running via ext:config
, without really having to
understand JXTA.
I ended up writing, with
gonzo holding my hand,
a 59-line JXTAConfig class that is pretty gnarly and
ugly and shows some problems with ext:config
and
does some things that I don’t 100% understand, but it seems to
robustly get a JXTA instance going, the only gotcha being that you can’t get
two different JVMs running JXTA in the same working directory.
OK, here’s the code; commentary follows:
1 package com.sun.whatever;
2
3 import java.io.File;
4 import java.io.FileOutputStream;
5 import java.io.PrintStream;
6 import net.jxta.exception.ConfiguratorException;
7 import net.jxta.ext.config.AbstractConfigurator;
8 import net.jxta.ext.config.Configurator;
9 import net.jxta.impl.protocol.PlatformConfig;
10
11 public class JXTAConfig extends AbstractConfigurator {
12 static final String[] profileContents = {
13 "<jxta>",
14 " <peer descriptor='edge'/>",
15 " <transport>",
16 " <tcp>",
17 " <address>",
18 " <multicast enabled='true'>udp://224.0.1.85:1234</multicast>",
19 " </address>",
20 " <publicAddress exclusive='false'/>",
21 " </tcp>",
22 " <http/>",
23 " </transport>",
24 "</jxta>"
25 };
26
27 private static Configurator configurator = null;
28 static {
29 String jxtaHome = System.getenv("JXTA_HOME");
30 if (jxtaHome == null)
31 jxtaHome = System.getProperty("user.dir") + "/.jxta";
32 try {
33 File dotJxta = new File(jxtaHome);
34 if (!dotJxta.isDirectory())
35 dotJxta.mkdir();
36 PrintStream out = new PrintStream(new File(dotJxta, "profile.xml"));
37 for (String line : profileContents)
38 out.println(line);
39 out.close();
40 configurator = new Configurator((new File(jxtaHome)).toURI());
41 } catch (Exception e) {
42 System.err.println("Problem initializing JXTA environment in " +
43 jxtaHome + ": " + e);
44 e.printStackTrace();
45 System.exit(1);
46 }
47 }
48
49 public JXTAConfig() {
50 super(configurator);
51 }
52
53 public PlatformConfig createPlatformConfig(Configurator c)
54 throws ConfiguratorException {
55 c.setName("SigridConfigurator");
56 c.setSecurity("foo", "X123456789");
57 return c.getPlatformConfig();
58 }
59 }
Then, to start JXTA you do:
AbstractConfigurator.register(JXTAConfig.class);
netpg = PeerGroupFactory.newNetPeerGroup();
This was originally based on a similar construct ripped out of the
MyJXTA source. The idea is that the
static initializer tells the JXTA system to configure itself from a file named
profile.xml
from the URI provided.
The trouble is that if profile.xml
is missing, it takes all the
defaults, and the defaults are to turn multicast-based discovery off.
Since multicast-based discovery is approximately the most useful thing about
JXTA, this strikes me as questionable.
Anyhow, James is the kind of engineer (the majority kind) who thinks that having an XML configuration file that allows you to set zillions of obscure options any old way you want is a good thing. Me, I’m just trying to enable low-rent autodiscovery on a local net without having to understand any of those JXTA options, and furthermore, every required directory and file makes installation trickier, so fuck the options, I just blast the minimal XML file to make things work into place. An argument could be made that I should check whether it’s already there before blasting away.
There are a few things obviously wrong with this approach, not least that
significant options are hardwired into a static initializer. James
has some ideas about what
the minimal startup ought to be. I’d go further, I’d want the minimal startup
to be nothing; just go ahead and call newNetPeerGroup()
and all the defaults just work.
And despite my brutal minimalism above, there are probably going to be apps
where the XML config file is appropriate; but you shouldn’t have to do this
static-init kludge to turn that on.