Вы находитесь на странице: 1из 13

Published on OpenP2P.com (http://www.openp2p.

com/)
See this if you're having trouble printing code examples

Learning the JXTA Shell


by Rael Dornfest
04/25/2001

I want to talk about the implications for that marvelous aspect of the fundamental UNIX design:
the pipe, and its ability to connect small independent programs so that they could collectively
perform functions beyond the capability of any of them alone. What is the equivalent of the pipe in
the age of the Web?
-- Tim O'Reilly, JavaOne Keynote: "The Network Really is the Computer."

The JXTA shell is a command-line interface to Sun's JXTA (pronounced "Juxta") peer-to-peer framework.
Originally written as a debugging tool for developers, the JXTA Shell affords a ground-floor view of the JXTA
environment, much like a traditional shell drops one into the thick of a *nix operating system.

The JXTA shell is a fine demonstration of some of the key features of the JXTA platform. The shell itself is
nothing more than a framework for dynamically loading and binding commands (read: classes) to the JXTA
underpinnings. This allows you, the user, to extend the shell to your heart's content. Who'll be the first to write
alias and less ;-)

As we'll see in this article, inter-peer messages in JXTA are nothing more than XML Table of Contents
documents, a fact that provides various interesting intersections with Web Services (via
XML-RPC and SOAP), syndication (via RSS), Instant Messaging a la Jabber, and •Login
more. •Old Favorites
•Getting to know me
This article is an introductory tour of the JXTA shell. We'll step through some of its •Peers
simple commands and move to more interesting examples constructed from these core •Peer Groups
building blocks. (For an overview of the JXTA platform, see the accompanying article, •P2P Piping
The JXTA Position.) •Can we talk?
•Logout
Anyone familiar with command-line shells, whether DOS or *nix, will feel right at •Gotchas!
home in the JXTA shell. There are basic commands: man, cat, env, grep, more,
and more. Commands can, of course, be sewed together using pipes to create compound commands: env | wc.
Multiple commands on one line are separated by semicolons: clear ; whoami ; man man. All in all, aside
from the fact that it's easy to forget that it's not a complete shell (see "Gotchas"), there are few surprises.

Login

First things first; we'll download, install and launch the JXTA shell.
First things first; we'll download, install and launch the JXTA shell.
Related Articles:
1. The JXTA Shell is freely downloadable from the Jxta.org site at
JXTA Takes Its
http://download.jxta.org/easyinstall/. Installers are available for various platforms,
as well as ZIP archives and CVS access. Position

Note: At the time of this writing, Windows 2000 users may have trouble with the JXTA Shell
commands
Windows installer launching and disappearing without doing much of anything,
save perhaps hanging around in the background. If this happens, you may want
The JuxtaNet
to download the latest nightly build.
"Hello, JXTA!"
2. Launch the JXTA shell by double-clicking on the jxta.exe icon in the shell
subdirectory of wherever you put the installation. Joy Announces JXTA

JXTA
Application
Icon

3. The first time you run the shell, the JXTA Configurator dialog will appear. Leave the defaults as they are;
all you need do is fill in a name for your peer (anything will do) in the Peer Name field and click the OK
button to move on.
The JXTA Configurator

4. The JXTA shell window should appear and you're ready to go.
The JXTA Shell

Note: I found a couple of bugs that can cause the shell not to launch. If, after closing the configurator, the
shell does not appear momentarily, double-click the jxta.exe icon to relaunch. Windows 2000 users may
find this makes no difference and will need to log out (not reboot, mind you) and log in again before
continuing.

This article was written using version 0.9 (build 14e, 04-22-2001). For versioning, type version at the
command-line.

Old Favorites

We'll start with a few old shell favorites.

If at any point you need help, the standard *nix man provides man(ual) pages for supported functionality.
Typing just man displays information about man itself, along with a list of available commands.

JXTA>man
The 'man' command is the primary manual system for the JXTA shell.
The usage of man is:

JXTA> man <commandName>

For instance typing


JXTA> man Shell
displays man page about the Shell

The following is the list of commands available:

cat Display the content of an environment variable


chpgrp Change the default peer group
...
who Display member identity in a peer group
whoami Display peer and peer-group information

JXTA>

(For a complete list of JXTA shell commands, see "JXTA Commands.")

env, as expected, displays all defined shell environment variables.

JXTA>env
peer0 = stored local peer advertisement
(class net.jxta.impl.protocol.PeerGroupAdv)
stdout = Default OutputPipe (class net.jxta.impl.shell.ShellOutputPipe)
stdin = Default InputPipe (class net.jxta.impl.shell.ShellInputPipe)
Shell = Root Shell (class net.jxta.impl.shell.bin.Shell.Shell)
consout = Default Console OutputPipe
(class net.jxta.impl.shell.ShellOutputPipe)
consin = Default Console InputPipe (class net.jxta.impl.shell.ShellInputPipe)
stdgroup = Default Group (class net.jxta.impl.peergroup.StdPeerGroup)

One thing to note in the above readout is that standard input (reading keyboard Have you
input) and output (displaying output to the console) are JXTA pipes, the same explored JXTA?
conduits by which peers communicate with each other. The same is true for the shell Tell us your first
console's consin/consout. We'll delve more into pipes in a bit. impressions and let
others know what
Here are a few more simple commands to try for fun:
you've learned so far.
man | wc Post your findings
env | grep -i stdin
cat peer0 | more
Shell -s

Getting to know me

Let's get to know ourselves a little, shall we? The whoami command functions as expected, albeit a little more
interesting than the standard printing of my username.

JXTA>whoami
<Peer>milne</Peer>
<Keywords>NetPeerGroup by default</Keywords>
<PeerId>jxta://59616261646162614A78746150325033237B7161401449269
6789EFFBC49968B0000000000000000000000000000000000000000000000000000000
000000301</PeerId>
<TransportAddress>tcp://1.2.3.4:6001/</TransportAddress>
<TransportAddress>http://JxtaHttpClient59616261646162614A7874615
0325033237B71614014492696789EFFBC49968B0000000000000000000000000000000
000000000000000000000000000000301/</TransportAddress>

JXTA>whoami -g
<PeerGroup>NetPeerGroup</PeerGroup>
<Keywords>NetPeerGroup by default</Keywords>
<PeerGroupId>jxta://59616261646162614A757874614D5047000000000000
0000000000000000000000000000000000000000000000000000000000000000000000
00000000000201</PeerGroupId>
<Service>jxta.service.resolver</Service>
<Service>jxta.service.membership</Service>
<Service>jxta.service.discovery</Service>
<Service>jxta.service.pipe</Service>
<Service>jxta.service.peerinfo</Service>
</code></pre>

The first whoami claims that I am a peer named "milne" with the unique identifier, "jxta://596162..." I am, by
default, a member of the "NetPeerGroup" -- more on groups in a moment. I am communicating via TCP
directly at IP address 1.2.3.4, port 6001, and via an HTTP proxy if behind a firewall/NAT. Note that even
though I may be using HTTP to get past my firewall, direct TCP communication is still useful for peers on my
LAN. The second whoami provides a little more detail about my current peer-group membership, including
group identifier and available services.

For more details, there's whoami -l . This is but a pretty representation of the actual peer advertisement,
viewable in its native XML by printing the "peer0" environment variable we saw above.

JXTA>whoami -l | more
jxta:PeerGroupAdvertisement :
Name : NetPeerGroup
PeerName : milne
Keywords : NetPeerGroup by default
Pid : jxta://59616261646162614A78746150325033237B7161401449269
6789EFFBC49968B0000000000000000000000000000000000000000
00000000000000000000301
Gid : jxta://59616261646162614A757874614D504700000000000000000
00000000000000000000000000000000000000000000000000000000
00000000000000000000201
isRendezvous : false
Services :
jxta:ServiceAdvertisement :
Name : jxta.service.resolver
Version : JXTA1.0
Keywords : resolver
PipeService :
Params : http://216.15.60.14:6002
Params : tcp://129.144.36.190:6001
Params : http://209.25.154.239:6002
Params : http://63.115.99.228:6002
Params : http://206.132.188.132:6002
Uri : http:/www.jxta.org/download/jxta.jar
Provider : sun.com
-----More-----
JXTA>cat peer0 | more
<?xml version="1.0"?>
<!DOCTYPE jxta:PeerGroupAdvertisement>
<jxta:PeerGroupAdvertisement>
<Name>NetPeerGroup</Name>
<PeerName>milne</PeerName>
<Keywords>NetPeerGroup by default</Keywords>
<Pid>jxta://59616261646162614A78746150325033237B7161401449269
6789EFFBC49968B00000000000000000000000000000000000000000
00000000000000000000301</Pid>
<Gid>jxta://59616261646162614A757874614D504700000000000000000
00000000000000000000000000000000000000000000000000000000
00000000000000000000201</Gid>
<isRendezvous>false</isRendezvous>
-----More-----

These settings reflect the initial JXTA configurator settings we breezed through earlier. To reconfigure your
JXTA peer from within the shell, take a gander at the peerconfig command (type: man peerconfig).

So much, then, for the preamble; let's get on to the interesting P2P pieces.

Peers

Each application tapping into JXTA is a peer. Your JXTA shell running on your desktop right now is a peer, as
is mine on my laptop. The peers command displays all peers already known to my peer, initially only myself
and possibly a peer I'm using as an intermediary outside my firewall/NAT.

JXTA>peers
peer0: name = milne
peer1: name = DIOXINE.NET

JXTA>peers -l [the -l option provides more detail]


peer0: ID = 38e6af70 name = milne
addr = http://JxtaHttpClient59616261646162614A787461503250337E00F
24A221C48BD8C09B1B5BA37BC9600000000000000000000000000000000000000
00000000000000000000000301/
peer1: ID = 796f3ac4 name = DIOXINE.NET
addr = http://jxta.dioxine.net:6002/

Discovering other peers, peers of peers and so on, is just a matter of propagating a remote discovery request
using peers -r.

JXTA>peers -r
peer discovery message sent

[time passes]

JXTA>peers
JXTA>peers
peer0: name = piglet
peer1: name = Platform PeerGroup
peer2: name = Platform PeerGroup
peer3: name = milne
peer4: name = NetPeerGroup by default
peer5: name = pooh
peer6: name = Platform PeerGroup
...

Discovered peers (technically, their peer announcements) are cached locally, stored in environment variables
"peer#" where # is the sequential integer associated with a particular peer. To flush all known peers and begin
again, use peers -f.

Peer Groups

Each peer belongs to a peer group. By default, each peer is a member of the global "NetPeerGroup" group,
analagous to a world without area codes, where every phone number is globally unique. The majority of the
time, however, we function within a particular community and can assume the presence of a limited number of
appropriate peers. A peer group logically limits the scope of peers with whom you will be communicating,
analagous to your local telephone area code. Upon joining a peer group, one sees only other member peers.

As with peers, to find out what groups are known to your peer, use the groups command; to propagate a group
remote discovery request, use groups -r

JXTA>groups
group0: name = NetPeerGroup

JXTA>groups -l [the -l option provides more detail]


group0: GID = 12274c77 name = NetPeerGroup
addr = http://JxtaHttpClient59616261646162614A787461503250337E00F
24A221C48BD8C09B1B5BA37BC9600000000000000000000000000000000000000
00000000000000000000000301/

JXTA>groups -r
group discovery message sent

[time passes]

JXTA>groups
group0: name = piglets
group1: name = tiggers
group2: name = test
group3: name = NetPeerGroup
group4: name = foo
group5: name = foofoo
...

To join a group, simply use join -d group# where "group#" is the environment variable in which the group
advertisement is stored. You are prompted for an identity; technically a UUID, anything will do. To leave, use
(surprisingly enough) leave. Here I join the "tiggers" group, look around for peers and leave.

JXTA>join -d group1

JXTA>whoami -g
<PeerGroup>tiggers</PeerGroup>
<Keywords>myhost</Keywords>
<PeerGroupId>jxta://3FEAEE2E776F4670AC5E81EB9B5BA4800000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000
00000201</PeerGroupId>
<Service>jxta.service.resolver</Service>
<Service>jxta.service.membership</Service>
<Service>jxta.service.discovery</Service>
<Service>jxta.service.pipe</Service>
<Service>jxta.service.peerinfo</Service>

JXTA>peers -r

[time passes]

JXTA>peers
peer0: name = tigger
peer1: name = milne
...

JXTA>leave
JXTA>

Discovered group announcements, like peers, are cached locally; flush them using groups -f.

P2P Piping

The JXTA shell extends the concept of the piping between local commands (as in man | wc) to inter-peer
communication. JXTA pipes are unidirectional and asynchronous.

Since JXTA pipes are asynchronous, an output pipe connection can be dynamically disconnected
and reconnected to a different input pipe. This disconnection operation can be performed multiple
times over the lifetime of the pipe. The ability to transparently redirect output of pipes is an
essential feature to build highly available services in a loosely coupled and unreliable environment
such as peer-to-peer networks. -- JXTA Shell Documentation (PDF)

While not quite as elegant as using the | character, piping from one peer to another in JXTA is almost trivial.
As an example, we'll open two shell windows (call them Pooh and Piglet) and pipe a couple of simple text
messages between them (from Piglet to Pooh). Pretend for a moment that these are two separate peers running
on machines on opposite sides of the Hundred Acre Wood.

JXTA>pipeadv = mkadv -p apipe


JXTA>inpipe = mkpipe -i pipeadv
JXTA>Shell -s
JXTA>pigletmsg = recv inpipe

First, Pooh creates a pipe advertisement and gives it a name ("pipeadv"). He uses this pipe advertisement to
create an input pipe ("inpipe") -- the receiving end. After launching another shell window (Shell -s) for
Piglet, an environment variable ("pigletmsg") is readied to receive input from our input pipe. We leave this shell
window in a waiting state and wander over to Piglet's.

JXTA>opipe = mkpipe -o pipeadv


JXTA>mymsg = mkmsg
JXTA>importfile -f hellopooh file1
JXTA>put mymsg hello file1
JXTA>importfile -f byepooh file2
JXTA>put mymsg bye file2
JXTA>send opipe mymsg

Piglet uses the same pipe advertisement to create an output pipe ("opipe"). A new message is created and stored
in the environment variable "mymsg." Now Piglet has created a couple of text files named hellopooh and
byepoo containing one line of text apiece. In turn, each file is imported and stuffed into the variables "file1" and
"file2." The contents are packed into "mymsg" with an associated arbitrary tag, so as to be able to sort them at
the other end. Finally, Piglet sends his message via the output pipe and ...

recv has received a message


JXTA>cat pigletmsg
Tag: hello
Body:
<?xml version="1.0"?>

<ShellDoc>
<Item>
Hello, Pooh!
</Item>
</ShellDoc>
Tag: bye
Body:
<?xml version="1.0"?>

<ShellDoc>
<Item>
Goodbye, Pooh!
</Item>
</ShellDoc>

JXTA>data1 = get pigletmsg hello


JXTA>cat data1
<?xml version="1.0"?>

<ShellDoc>
<Item>
Hello, Pooh!
</Item>
</ShellDoc>
JXTA>data2 = get pigletmsg bye
JXTA>cat data2
<?xml version="1.0"?>

<ShellDoc>
<Item>
Goodbye, Pooh!
</Item>
</ShellDoc>
Instantly (or so the theory goes), Pooh receives Piglet's message. Simply printing the value of the "pigletmsg"
variable reveals a message composed of a couple of XML documents and the associated tags given to them by
Piglet. Instead of simply being displayed, individual documents can be extracted from the message and assigned
to a variable using the get command.

Since inter-peer messages are nothing more than XML documents, this provides various interesting
intersections with Web Services (via XML-RPC and SOAP), syndication (via RSS), Instant Messaging a la
Jabber, and more.

Can we talk?

While the example above provided some insight into message passing via pipes under JXTA, the shell does
actually have some rudimentary instant-messaging functionality. More a piping demonstration than anything
else, talk resembles the *nix write functionality, with each peer establishing its own talk connection to the
other.

JXTA>talk -register pooh


......
User : pooh is now registered
JXTA>talk -login pooh
JXTA>talk piglet
......
talk: piglet is not a registered user
JXTA>Shell -s

Pooh registers a talk user (read: talk advertisement) "pooh" and logs in (read: starts a listener daemon). He tries
to find Piglet, who has not yet registered as a talk user. We use Shell -s to create a new shell for Piglet.

JXTA>talk -register piglet


......
User : piglet is now registered
JXTA>talk -login piglet

Piglet creates a talk user "piglet" and logs in.

JXTA>talk piglet
found user's advertisement attempting to connect
talk is connected to user piglet
Type your message. To exit, type "." at begining of line
Hello, Piglet!

Pooh tries again, this time successful in finding Piglet and sending him a greeting.

JXTA>talk: from jxta://59616261646162614A787461503250333DA927976125


4559B209922BACA69E190000000000000000000000000000000000000000000000000
000000000000301 to piglet
Message: Hello, Piglet!
JXTA>talk -u piglet pooh
found user's advertisement attempting to connect
talk is connected to user pooh
Type your message. To exit, type "." at begining of line
And a hello to you too, Pooh.

Piglet receives Pooh's message -- albeit in rather ugly form. Now, Piglet can't simply reply to Pooh, as talk is a
one-way piped message. So Piglet establishes his own talk session to Pooh. You'll notice the slightly different
form of talk -u piglet pooh, resulting in a much cleaner message with proper attribution in Pooh's shell.

JXTA>talk piglet
found user's advertisement attempting to connect
talk is connected to user piglet
Type your message. To exit, type "." at begining of line
Hello, Piglet!

talk: from piglet to pooh


Message: And a hello to you too, Pooh.

.
JXTA>talk -logout pooh
JXTA>talk: stop listening for user :pooh

Once our friends are ready to conclude their chat, each enters a period on a line by itself and optionally logs out.
Note that talk advertisements created by talk -register hang around between shell sessions; before one can
chat, however, one must talk -login to start a new listener.

Incidently, as I mentioned a moment ago, a talk registration is simply a JXTA advertisement stored in a local
environment variable. We can take a closer look using our old friends, env and cat.

JXTA>env
stdout = Default OutputPipe (class net.jxta.impl.shell.ShellOutputPipe)
stdin = Default InputPipe (class net.jxta.impl.shell.ShellInputPipe)
...
adv0 = local jxta advertisement (class net.jxta.impl.protocol.PipeAdv)
stdgroup = Default Group (class net.jxta.impl.peergroup.StdPeerGroup)

JXTA>cat adv0
<?xml version="1.0"?>

<!DOCTYPE jxta:PipeAdvertisement>

<jxta:PipeAdvertisement>
<id>
jxta://59616261646162614A787461503250333DA9279761254559B209922
BACA69E1900000000000000000000000000000000000000000000000000000
00000000301
</id>
<name>
JxtaTalkUserName:pooh
</name>
</jxta:PipeAdvertisement>
Hardly user-friendly in its shell implemention, such talk functionality has already been implemented in
InstantP2P, a Java AWT-based GUI chat/file-sharing demonstration application.

Logout

To log out of the JXTA shell, type exit at the prompt or just close the shell window. Quite a bit of information
is retained between shell sessions including settings, cached peers, groups and other advertisements. To clear
your peer or group caches, use the -f option mentioned earlier. To start from scratch, delete the following
files/directories: PlatformConfig, PlatformPeerGroup, jxtaConfig, and cm.

Gotchas!

Bear in mind that the JXTA shell is only for demonstration and debugging purposes and should not be relied
upon to be absolutely stable or emulate a full shell. At the time of this writing, there are a few gotchas and bugs:

As mentioned above, Windows 2000 users may need to skip the installer and download the latest nightly
build ZIP file.
Sometimes launching the shell does absolutely nothing. Windows (espectially Windows 2000) users may
need to log out and back in, or even reboot.
Shells spawned via Shell -s are not truly independent. Closing or exiting from the primary shell closes
the entire application and all windows.
Ctrl commands behave very much as Windows GUI users expect, and completely confounds those more
at home on the DOS or *nix command-line. ^C isn't interrupt and ^Z isn't suspend; the former copies
selected text and the latter does nothing at all. See http://shell.jxta.org/issues/show_bug.cgi?id=2
Talk is currently extremely slow when not simply talking to yourself from one shell window to another.

Where to go for more...

JXTA.org
The JXTA Position
Project JXTA Documents
JXTA Shell Quick Start Guide
JXTA Shell commands
"Hello, JXTA!"

Disclosure: The author has been a member of the JXTA's Technical Advisory Committee during its pre-launch
development.
Copyright © 2009 O'Reilly Media, Inc.

Вам также может понравиться