https://protegewiki.stanford.edu/api.php?action=feedcontributions&user=Dustinburke&feedformat=atomProtege Wiki - User contributions [en]2024-03-29T02:36:37ZUser contributionsMediaWiki 1.27.7https://protegewiki.stanford.edu/index.php?title=Troubleshooting_Client_Server_Connections&diff=7071Troubleshooting Client Server Connections2010-03-05T18:55:18Z<p>Dustinburke: /* Configuration */</p>
<hr />
<div><div class="orangeBox"><br />
<span class="orangeBoxTitle">Client-Server Troubleshooting</span><br /><br /><br />
<br />
'''This page is in the very early stages.'''<br />
<br />
</div><br />
<br />
<br />
__TOC__<br />
<br />
<br />
= Basics =<br />
<br />
In troubleshooting, it is very useful to understand that the client will first connect to the rmi registry to get a reference to the server and then will use the server reference to contact the server.<br />
This protocol is discussed [[Protege_Client_Server_RMI|here]] (ignore the black magic tricks unless they help you get a better understanding).<br />
<br />
The first thing to do is to look at any messages on the client and server console. The most fundamental error that can arise is the following exception which appears on the client console:<br />
<pre><br />
SEVERE: java.rmi.ConnectException: Connection refused to host: localhost; nested exception is: <br />
java.net.ConnectException: Connection refused<br />
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)<br />
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)<br />
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)<br />
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306)<br />
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)<br />
at java.rmi.Naming.lookup(Naming.java:84)<br />
at edu.stanford.smi.protege.server.ServerPanel.connectToHost(ServerPanel.java:140)<br />
</pre><br />
Note that the exception happens when trying to call Naming.lookup. Usually the client will pop up a window that says ''Unable to Connect to Server''. This means that the client could not connect to the rmiregistry. Possibly the rmiregistry is not running or there is a firewall or other network problem.<br />
<br />
An alternate very different error that appears on the client console is the following exception<br />
<pre><br />
SEVERE: java.rmi.ConnectException: Connection refused to host: 67.180.198.51; nested exception is: <br />
java.net.ConnectException: Connection timed out<br />
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)<br />
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)<br />
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)<br />
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:94)<br />
at edu.stanford.smi.protege.server.Server_Stub.openSession(Unknown Source)<br />
at edu.stanford.smi.protege.server.ServerPanel.createSession(ServerPanel.java:154))<br />
</pre><br />
This is usually accompanied by the message ''Failed to create a session because of either an invalid username/password combination, or a firewall problem''. Unfortunately this pop up dialog is very ambiguous and can mean many things. It is for this reason that we have tried to add some additional information to help. In any case the exception tells us two very important things. First the problem occurs during an attempt ot create a session (ServerPanel.createSession) when the client makes a call to the server (Server_Stub.openSession(Unknown Source). In particular, since the client is talking to the server, it means that it has already talked to the rmiregistry to obtain a pointer to the client. That is, this exception means that the client has gotten quite a bit further than it had in the previous case.<br />
<br />
Note that the connection is being refused to the host 67.180.198.51. It is important to look at this because this is often the problem - the connection is being made to the wrong place. There is another message that amplifies on this issue:<br />
<pre><br />
Server ref = Server_Stub[UnicastRef2 [liveRef: [endpoint:[67.180.198.51:38547,edu.stanford.smi.protege.server.socket.RmiSocketFactory@2](remote),objID:[-4da377e5:122e64da065:-8000, 0]]]]<br />
</pre><br />
This is a printout of the server reference that (1) the server passed to the rmiregistry at server startup and (2) the rmiregistry gave to the client to tell it how to contact the server. Not the endpoint:<br />
<pre><br />
67.180.198.51:38547.<br />
</pre><br />
This is the host and port that the rmiregistry thinks should be used to connect to the server. The Connection Refused exception suggests that there is some problem with this.<br />
<br />
One problem that can occur is that the server misrepresents itself when talking to the rmiregistry. At this point it is worth taking a glance at the first few paragraphs of [[Protege_Client_Server_RMI|description of the rmi protocol]]. The server decides how to represent itself to the based on the line:<br />
<pre><br />
-Djava.rmi.server.hostname=`hostname`<br />
</pre><br />
Sometimes this line doesn't do the right thing because the ''hostname'' command returns the wrong value. For instance, perhaps the hostname parameter returns ''smi-tredmond-li'' instead of ''smi-tredmond-li.stanford.edu''. Perhaps, depending on your network configuration, first of these can be resolved by the client and the second cannot. Another thing that the ''hostname'' command sometimes returns is ''localhost'' which will not work for any client on a different machine than the server.<br />
<br />
The client console/log is not the only place to look for hints about a problem. The server console can also have useful information. For example, if I simply supply the wrong user name or password, the server prints out a message<br />
<pre><br />
WARNING: Failed login for user Timothy Redmond IP: 127.0.1.1 -- Server.openSession()<br />
</pre><br />
In addition no server or client-side exceptions are generated.<br />
This means that the client successfully contacted the server, the server successfully processed the request but rejected it because the credentials were wrong.<br />
<br />
<br />
= Versioning Problems and UnmarshalExceptions =<br />
<br />
In order to have a Protege client work reliably with a Protege server, both must be running exactly the same version of Protege. There are several things that can go wrong when the version numbers are different. But the most obvious exception is an UnmarshalException which looks something like the following:<br />
<pre><br />
WARNING: Could not connect to remote project Collaborative Pizza -- java.lang.RuntimeException: java.rmi.UnmarshalException: error unmarshalling return; nested exception is: <br />
java.io.InvalidClassException: edu.stanford.smi.protege.server.update.ValueUpdate; local class incompatible: stream classdesc serialVersionUID = -7753881900765528485, local class serialVersionUID = -4059275656078639103<br />
at edu.stanford.smi.protege.server.framestore.RemoteClientFrameStore.convertException(RemoteClientFrameStore.java:388)<br />
at edu.stanford.smi.protege.server.framestore.RemoteClientFrameStore.getFrame(RemoteClientFrameStore.java:509)<br />
at edu.stanford.smi.protege.model.framestore.ModificationFrameStore.getFrame(ModificationFrameStore.java:26)<br />
at edu.stanford.smi.protege.model.framestore.ArgumentCheckingFrameStore.getFrame(ArgumentCheckingFrameStore.java:107)<br />
</pre><br />
<br />
There are some other things that can go wrong when the client and the server have different versions. In particular another type of error that we saw recently involved a client that used certain remote jobs that the server did not know about. This raised the following exception (seen on the client):<br />
<pre><br />
WARNING: edu.stanford.smi.protege.exception.ProtegeIOException: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: <br />
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: <br />
java.lang.ClassNotFoundException: null class<br />
at edu.stanford.smi.protege.server.framestore.RemoteClientFrameStore.executeProtegeJob(RemoteClientFrameStore.java:1691)<br />
at edu.stanford.smi.protege.util.ProtegeJob.execute(ProtegeJob.java:94)<br />
...<br />
</pre><br />
The key hint here is that the error occurred during executeProtegeJob. The error happened on the server (who is not able to find a class passed to it from the client) and is displayed on the client. This type of exception suggests that the client and server are running different versions of Protege or that the server needs to be running a plugin that is running on the client.<br />
<br />
<br />
= RMI Registry Synchronization =<br />
<br />
Sometime, not very often, a problem arises where the rmiregistry needs to be restarted. So if the client-server has been running fine and you are suddenly having mysterious problems, try killing the rmiregistry and restarting it. I don't know anyone who understands this issue.<br />
<br />
<br />
= Networks, Firewalls and Telnet =<br />
<br />
It is out of scope for the Protege team to diagnose network problems. There are simply too many things that can go wrong and too many things to know. The primary indicator that you need to start thinking about netowrk issues is that the server works fine on localhost or on the lan but not from outside the lan. In this case, telnet is a useful tool for quickly evaluating where a problem is located. All real operating systems with possibly (grudgingly admitted) one exception have a telnet command. If your operating system is under configured you can try this link for [http://www.arsgeek.com/2007/03/20/enable-telnet-in-windows-vista/ enabling telnet] or [http://www.chiark.greenend.org.uk/~sgtatham/putty/]. I haven't tried either but you should also feel free to complain to your vendor for leaving out such a basic diagnostic command.<br />
<br />
What telnet does is to allow you to connect to a hostname and a port. If you know a protocol in detail it is also possible (usually not recommended) to talk a bit with a server this way. For example, using the host www.google.com and port 80 you can try ''GET /''. There are also instructions on various web pages for talking with mail servers, etc. In our case, all we are interested in is whether the client can connect. So depending on your telnet client, a successful connection will look something like this:<br />
<pre><br />
[tredmond@smi-tredmond-li org.protege.osgi.jdbc.prefs]$ telnet smi-tredmond-li 5100<br />
Trying 127.0.1.1...<br />
Connected to smi-tredmond-li.<br />
Escape character is '^]'.<br />
</pre><br />
At this point, with this client, type control-] and then quit and telnet will exit. In the case of a problem, it may take a bit of time for telnet to realize that it cannot connect. In the case that it can connect, it usually connects very quickly.<br />
<br />
There are two connections that need to be tested. The first connection is the connection to the rmiregistry. By default the rmi registry runs on port 1099 but it can be changed when the rmi registry is invoked with the command <br />
<pre><br />
rmiregisty [port #].<br />
</pre><br />
In addition the server is configured to talk to a particular rmiregistry port with the jvm definition <br />
<pre><br />
-Dprotege.rmi.registry.port=[port #].<br />
</pre> <br />
The rmi registry port that the server is using can also be seen in the server console message near the top:<br />
<pre><br />
Server port = 5200, registry port = 5100, compressed stream<br />
</pre><br />
The other connection that needs to be tested is the server connection. The server port can be determined if you have a server reference message in some clients logs:<br />
<pre><br />
Server ref = Server_Stub[UnicastRef2 [liveRef: [endpoint:[67.180.198.51:38547,edu.stanford.smi.protege.server.socket.RmiSocketFactory@2](remote),objID:[-4da377e5:122e64da065:-8000, 0]]]]<br />
</pre><br />
but the easiest way to know the server port is to set it with a jvm definition:<br />
<pre><br />
-Dprotege.rmi.server.port=5200.<br />
</pre><br />
If telnet cannot connect then neither will Protege and the problem is to figure out why the connection failed. This telnet test can be run from different machines on your network to determine exactly what is causing a problem with the network.<br />
<br />
== Configuration ==<br />
To resolve configuration issues arising from NAT firewalls, here's a simple walkthrough that hopefully helps someone. <br />
<br />
* In your Protege client application, edit the "protege.properties" file in the installation directory and add the line (or modify if it already exists), where ''hostname'' is the HOSTNAME (not the domain name) and ''RMI_REG_PORT'' is the RMI Registry Port. By default this is 1099, but can be changed from the server configuration. The global IP Address of the server also works in place of the hostname, but a common mistake is to set this to the local IP address of the server. <br />
edu.stanford.smi.protege.server.ServerPanel.host_name=''hostname''\:''RMI_REG_PORT''<br />
* In your Protege Server installation, make the following changes to "run_protege_server.sh":<br />
** For the HOSTNAME_PARAM variable, replace `hostname` with the actual hostname of your machine (same as specified from the client side so you know its globally-routable). A common mistake is to set this to "localhost" or to a locally routable hostname.<br />
** Add the following lines before the PORTOPTS variable is defined:<br />
RMI_REG_PORT=1099<br />
RMI_SERV_PORT=5200<br />
** Uncomment the line defining the PORTOPTS variable and change it to:<br />
PORTOPTS="-Dprotege.rmi.server.port=$RMI_SERV_PORT -Dprotege.rmi.registry.port=$RMI_REG_PORT"<br />
** Add the RMI_REG_PORT argument to the rmiregistry command, like this:<br />
$JAVA_PATH/rmiregistry $RMI_REG_PORT &<br />
* Make sure you configure your firewall to allow TCP traffic to the RMI_REG_PORT and RMI_SERV_PORT<br />
<br />
= See Also =<br />
* [[Protege Client Server Tutorial Advanced]]</div>Dustinburkehttps://protegewiki.stanford.edu/index.php?title=Protege_Client_Server_Tutorial_Advanced&diff=7070Protege Client Server Tutorial Advanced2010-03-05T18:54:52Z<p>Dustinburke: </p>
<hr />
<div><div class="orangeBox"><br />
<span class="orangeBoxTitle">Protege Server - Advanced Topics</span><br /><br /><br />
'''This page describes advanced topics related to the Protege server including: <br />
* Running the Protege server as a Windows Service<br />
* Working with Firewalls<br />
* Configuration Settings in the start-up scripts of the server and client<br />
* Debug and Performance Monitoring<br />
* Accessing the Server Programmatically<br />
<br />
This page is part of the [[Protege_Client-Server_Tutorial|Protege client-server tutorial]].'''<br />
<br />
</div><br /><br /><br />
<br />
__TOC__<br />
<br />
= How Does RMI Work? =<br />
<br />
We recommend that you take a look at the [[Protege_Client_Server_RMI|How RMI Works wiki page]]. This will help you better understand and debug RMI related problems.<br />
<br />
<br />
= Running as a Windows Service =<br />
<br />
In some cases it may be desirable to have the Protege server start as a Windows service. The easiest way to do this is to use the Windows Resource Toolkit which includes the AutoExNt utility. This utility allows Windows batch files to run as a service. Create an Autoexnt.bat file (as per instructions here: http://support.microsoft.com/kb/243486) that changes into your Protege directory and then runs the server. To follow is an example batch file:<br />
<br />
<code><pre><br />
@echo off<br />
C:<br />
cd “\Program Files\Protege”<br />
run_protege_server.bat<br />
</pre></code><br />
<br />
Once you have completed all the steps in the knowledge base article you will note that the service name is still “AutoExNT”. You can adjust this by using regedit to change the value of the following key to “Protege Server” (the change will not be visible until the server is restarted):<br />
<br />
<code>HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\AutoExNT\DisplayName</code><br />
<br />
<br />
= Working with Firewalls =<br />
<br />
If the Protege server is running inside a firewall, '''you need to open two ports to ensure access from outside the firewall'''. One port is for the rmiregistry and the other port is for the Protege server.<br />
<br />
To set the port that the rmiregistry listens on (the default is 1099), the rmiregistry command must be invoked as:<br />
<br />
<code><pre>rmiregistry portNumber</pre></code><br />
<br />
For a more specific example, suppose that we use port 5100 for the rmiregistry and we start rmiregistry with the command:<br />
<br />
<code><pre>rmiregistry 5100</pre></code><br />
<br />
<br />
We will also need to tell the Protege server what port to use to access the rmiregistry. This is done by in one of the following ways:<br />
<br />
<br />
'''1. If you ran Protege server using the run_protege_server script''', then you need to uncomment the line that starts with PORTOPTS:<br />
<br />
'''In Linux/Mac OSX''':<br />
<br />
Uncomment the line (remove # at the beginning of line; already done below):<br />
<br />
<code><pre>PORTOPTS="-Dprotege.rmi.server.port=5200 -Dprotege.rmi.registry.port=5100"</pre></code><br />
<br />
'''In Windows''':<br />
<br />
Uncomment the line (remove "rem" at the beginning of line; already done below):<br />
<br />
<code><pre>set "PORTOPTS=-Dprotege.rmi.server.port=5200 -Dprotege.rmi.registry.port=5100"</pre></code><br />
<br />
<br />
'''2. If you ran Protege server using the Advanced method (making commands in the console)''', then you need to set 2 JVM arguments:<br />
<br />
<code><pre>-Dprotege.rmi.registry.port=5100</pre></code><br />
<br />
Suppose we choose port 5200 for the Protege server to listen on. We tell the Protege server to use this port with the following JVM option:<br />
<br />
<code><pre>protege.rmi.server.port=5200</pre></code><br />
<br />
An example of these server settings can be found in the <protege-install-dir>/run_protege_server.sh Unix shell script.<br />
<br />
<br />
<br />
Finally, when we log in from a Protege client, we need to tell the client where to find the rmiregistry. This is done by appending :5100 to the hostname in the rmiregistry connection screen:<br />
<br />
<code><pre>smi-protege.stanford.edu:5100</pre></code><br />
<br />
<br />
The Protege client will determine how to find the Protege server when it contacts the rmiregistry.<br />
<br />
Another important problem to solve is NAT (Network Address Translation): the IP address of the Protege server host is not the same inside the local network (for example 192.168.1.xxx) as it is outside the network (for example 9.154.38.47). To overcome this (but often losing the ability to access the Protege server from inside the network), you have to add -Djava.rmi.server.hostname=9.154.38.47 to the JVM start options of the Protege server.<br />
<br />
Remember, you often have to restart the rmiregistry for changes to take effect.<br />
<br />
<br />
= Configuration Settings =<br />
<br />
There are several settings that can be configured in the client-server mode. <br />
<br />
<br />
== Server Side Settings ==<br />
<br />
We have discussed some of the system properties:<br />
<br />
<code><pre><br />
-Dprotege.rmi.server.port=...<br />
-Dprotege.rmi.registry.prot=...<br />
</pre></code><br />
<br />
... above. There is another setting that can be very important for performance:<br />
<code><pre><br />
-Dserver.use.compression=true<br />
</pre></code><br />
This option enables compression on the client-server connection. It will increase the cpu usage on the client and the server but can provide quite a significant improvement in bandwidth usage (early experiments suggest a a compression factor of up to 10 to 1 and performance on the client is doubled for some large ontologies).<br />
<br />
Finally, the option:<br />
<br />
<code><pre>-Dtransaction.level=...</pre></code><br />
<br />
... controls the level of protection associated with transactions. The options are:<br />
<br />
* NONE - which means that transactions do not even have rollback capabilities. This is not recommended.<br />
* READ_UNCOMMITTED - which means that users can see other users changes even if the other user is in a transaction and has not committed the transaction.<br />
* READ_COMMITTED - which means that user operations made during a transaction are not seen by other users until they are committed.<br />
* REPEATABLE_READ - which means that the system assures a user in a transaction that data he reads will not change for the duration of the transaction.<br />
* SERIALIZABLE - which means that transactions are serializable. This is the most stringent form of transaction processing but it is also the most expensive and the most likely to cause problems with locked databases.<br />
<br />
<br />
== Client Side Settings ==<br />
<br />
There are also optimizations that allow the user to control caching on the client. On the client side the user can specify that certain data on the server will cache information about certain frames from the server side ontology while the client initializes. For example, if the client adds the system properties:<br />
<br />
<code><pre><br />
-Dserver.client.preload0=http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl#Oncogene_TIM<br />
-Dserver.client.preload1=http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl#Diagnostic_Therapeutic_and_Research_Equipment<br />
</pre></code><br />
<br />
... then the client will preload Oncogene_TIM and Diagnostic_Therapeutic_and_Research_Equipment and their parents before it starts up. For large ontologies and bad network latency this can allow a user to start editing a selected set of classes without having to wait for the client to get the data from the server. The initialization of these classes is included in the Protege client startup.<br />
<br />
The option:<br />
<br />
<code><pre>-Dserver.client.preload.skip=true</pre></code><br />
<br />
... disables the pre-caching of frames on the client during the Protege client initialization process. The option:<br />
<br />
<code><pre>-Dpreload.frame.limit=...</pre></code><br />
<br />
... limits the number of frames that the client will preload during initilialization.<br />
<br />
<br />
= Debug and Performance Monitoring =<br />
<br />
== Client or Server Side Settings ==<br />
<br />
We have several tools to monitor and debug the performance of the Protege client-server. The logging.properties settings:<br />
<code><pre><br />
java.util.logging.ConsoleHandler.level=FINE<br />
<br />
...<br />
<br />
edu.stanford.smi.protege.server.socket.MonitoringInputStream.level=FINE<br />
edu.stanford.smi.protege.server.socket.CompressingInputStream.level=FINE<br />
</pre></code><br />
will start a reasonable amount of logging that will give you some idea of what traffic is going across the wire. These settings can be used on either the server or the client and they will measure and report on the low level traffic being received by rmi. The vast majority of the traffic is going from the server to the client so we anticipate that this setting will generally be used on the client.<br />
Here is a sampling of the information generated <br />
<code><pre><br />
Average Compression Ratio = 10.412 to 1, Compressed = 0.27 MB, Uncompressed = 2.76 MB (Cumulative)<br />
InputStream 0: 3 megabytes read<br />
Average Compression Ratio = 11.277 to 1, Compressed = 0.33 MB, Uncompressed = 3.77 MB (Cumulative)<br />
</pre></code><br />
The input stream line shows the data read from the socket. The compression ratio lines show the difference between the compressed data that actually goes over the wire and the uncompressed data that is read by the caller.<br />
<br />
<br />
== Client Side Settings ==<br />
<br />
In addition we have tools for simulating real world delays in a localhost setting. The following setting only applies on the client:<br />
<code><pre><br />
-Dserver.delay=80 <br />
</pre></code><br />
Note that in previous versions of Protege the server.delay option was set on the server side. This setting simulates an 80 millisecond delay for the latency associated with each rmi call. This is a very large delay for latency (a single call is noticeable by a Protege user) but experience has shown that this value does appear in real world installations.<br />
<br />
In addition, we have the following jvm properties that can be applied on either the server or the client:<br />
<code><pre><br />
-Dserver.upload.kilobytes.second=128 -Dserver.download.kilobytes.second=500<br />
</pre></code><br />
However we anticipate that these settings will be more useful if applied on the client because then a profiler, such as [http://www.yourkit.com YourKit], can determine how much time is being used for latency and how much time is being used for downloads and uploads. If set on the client the upload time tells the client to simulate delays to mimic a transfer rate for data from the client to the server and the download time tells the client to simulate delats to mimic the transfer rate for data from the server to the client.<br />
Note that some tools measure upload and bandwidth in kilobits per second. So a dsl connection with 6 megabits/second download and 512 megabits/second upload is getting 768 Kilobytes/second download and 64 Kilobytes/second upload.<br />
<br />
<br />
= Accessing the Server Programatically =<br />
<br />
To follow is an example of how to access the remote server programatically:<br />
<br />
<code><pre><br />
RemoteProjectManager rpm = RemoteProjectManager.getInstance();<br />
Project p = rpm.getProject("localhost", "Timothy Redmond", "troglodyte", "Newspaper", true);<br />
KnowledgeBase kb = p.getKnowledgeBase();<br />
</pre></code><br />
<br />
The code in the box below is another more complicated method that eases the process of opening multiple projects. This approach will allow you to use the same session object to retrieve different remote projects, but you cannot use the same session to open a single project twice.<br />
<br />
<code><pre><br />
Project p = null;<br />
try {<br />
RemoteServer server = (RemoteServer) Naming.lookup("//localhost/" + Server.getBoundName());<br />
if (server != null) {<br />
RemoteSession session = server.openSession("Timothy Redmond",<br />
SystemUtilities.getMachineIpAddress(), <br />
"troglodyte");<br />
if (session != null) {<br />
RemoteServerProject serverProject = server.openProject("Newspaper", session);<br />
if (serverProject != null) {<br />
p = RemoteClientProject.createProject(server, serverProject, session, true);<br />
}<br />
}<br />
}<br />
} catch (Exception e) {<br />
Log.getLogger().severe(Log.toString(e));<br />
}<br />
</pre></code><br />
Some other methods in the RemoteServer interface that may be of interest are<br />
* getAvailableProjectNames(RemoteSession)<br />
* allowsCreateUsers()<br />
* createUser(String, String)<br />
* createProject(...)<br />
* shutdown()<br />
To disconnect from the server, you only need to call the <code>dispose</code> method on the client side project:<br />
<br />
<code><pre><br />
p.dispose();<br />
</pre></code><br />
<br />
<br />
'''Read more about the Protege multi-user support in the [[Protege_Client-Server_Tutorial|Protege client-server tutorial]].'''<br />
<br />
= See Also =<br />
* [[Troubleshooting Client Server Connections]]</div>Dustinburkehttps://protegewiki.stanford.edu/index.php?title=Troubleshooting_Client_Server_Connections&diff=7069Troubleshooting Client Server Connections2010-03-05T18:52:16Z<p>Dustinburke: /* Configuration */</p>
<hr />
<div><div class="orangeBox"><br />
<span class="orangeBoxTitle">Client-Server Troubleshooting</span><br /><br /><br />
<br />
'''This page is in the very early stages.'''<br />
<br />
</div><br />
<br />
<br />
__TOC__<br />
<br />
<br />
= Basics =<br />
<br />
In troubleshooting, it is very useful to understand that the client will first connect to the rmi registry to get a reference to the server and then will use the server reference to contact the server.<br />
This protocol is discussed [[Protege_Client_Server_RMI|here]] (ignore the black magic tricks unless they help you get a better understanding).<br />
<br />
The first thing to do is to look at any messages on the client and server console. The most fundamental error that can arise is the following exception which appears on the client console:<br />
<pre><br />
SEVERE: java.rmi.ConnectException: Connection refused to host: localhost; nested exception is: <br />
java.net.ConnectException: Connection refused<br />
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)<br />
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)<br />
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)<br />
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306)<br />
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)<br />
at java.rmi.Naming.lookup(Naming.java:84)<br />
at edu.stanford.smi.protege.server.ServerPanel.connectToHost(ServerPanel.java:140)<br />
</pre><br />
Note that the exception happens when trying to call Naming.lookup. Usually the client will pop up a window that says ''Unable to Connect to Server''. This means that the client could not connect to the rmiregistry. Possibly the rmiregistry is not running or there is a firewall or other network problem.<br />
<br />
An alternate very different error that appears on the client console is the following exception<br />
<pre><br />
SEVERE: java.rmi.ConnectException: Connection refused to host: 67.180.198.51; nested exception is: <br />
java.net.ConnectException: Connection timed out<br />
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)<br />
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)<br />
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)<br />
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:94)<br />
at edu.stanford.smi.protege.server.Server_Stub.openSession(Unknown Source)<br />
at edu.stanford.smi.protege.server.ServerPanel.createSession(ServerPanel.java:154))<br />
</pre><br />
This is usually accompanied by the message ''Failed to create a session because of either an invalid username/password combination, or a firewall problem''. Unfortunately this pop up dialog is very ambiguous and can mean many things. It is for this reason that we have tried to add some additional information to help. In any case the exception tells us two very important things. First the problem occurs during an attempt ot create a session (ServerPanel.createSession) when the client makes a call to the server (Server_Stub.openSession(Unknown Source). In particular, since the client is talking to the server, it means that it has already talked to the rmiregistry to obtain a pointer to the client. That is, this exception means that the client has gotten quite a bit further than it had in the previous case.<br />
<br />
Note that the connection is being refused to the host 67.180.198.51. It is important to look at this because this is often the problem - the connection is being made to the wrong place. There is another message that amplifies on this issue:<br />
<pre><br />
Server ref = Server_Stub[UnicastRef2 [liveRef: [endpoint:[67.180.198.51:38547,edu.stanford.smi.protege.server.socket.RmiSocketFactory@2](remote),objID:[-4da377e5:122e64da065:-8000, 0]]]]<br />
</pre><br />
This is a printout of the server reference that (1) the server passed to the rmiregistry at server startup and (2) the rmiregistry gave to the client to tell it how to contact the server. Not the endpoint:<br />
<pre><br />
67.180.198.51:38547.<br />
</pre><br />
This is the host and port that the rmiregistry thinks should be used to connect to the server. The Connection Refused exception suggests that there is some problem with this.<br />
<br />
One problem that can occur is that the server misrepresents itself when talking to the rmiregistry. At this point it is worth taking a glance at the first few paragraphs of [[Protege_Client_Server_RMI|description of the rmi protocol]]. The server decides how to represent itself to the based on the line:<br />
<pre><br />
-Djava.rmi.server.hostname=`hostname`<br />
</pre><br />
Sometimes this line doesn't do the right thing because the ''hostname'' command returns the wrong value. For instance, perhaps the hostname parameter returns ''smi-tredmond-li'' instead of ''smi-tredmond-li.stanford.edu''. Perhaps, depending on your network configuration, first of these can be resolved by the client and the second cannot. Another thing that the ''hostname'' command sometimes returns is ''localhost'' which will not work for any client on a different machine than the server.<br />
<br />
The client console/log is not the only place to look for hints about a problem. The server console can also have useful information. For example, if I simply supply the wrong user name or password, the server prints out a message<br />
<pre><br />
WARNING: Failed login for user Timothy Redmond IP: 127.0.1.1 -- Server.openSession()<br />
</pre><br />
In addition no server or client-side exceptions are generated.<br />
This means that the client successfully contacted the server, the server successfully processed the request but rejected it because the credentials were wrong.<br />
<br />
<br />
= Versioning Problems and UnmarshalExceptions =<br />
<br />
In order to have a Protege client work reliably with a Protege server, both must be running exactly the same version of Protege. There are several things that can go wrong when the version numbers are different. But the most obvious exception is an UnmarshalException which looks something like the following:<br />
<pre><br />
WARNING: Could not connect to remote project Collaborative Pizza -- java.lang.RuntimeException: java.rmi.UnmarshalException: error unmarshalling return; nested exception is: <br />
java.io.InvalidClassException: edu.stanford.smi.protege.server.update.ValueUpdate; local class incompatible: stream classdesc serialVersionUID = -7753881900765528485, local class serialVersionUID = -4059275656078639103<br />
at edu.stanford.smi.protege.server.framestore.RemoteClientFrameStore.convertException(RemoteClientFrameStore.java:388)<br />
at edu.stanford.smi.protege.server.framestore.RemoteClientFrameStore.getFrame(RemoteClientFrameStore.java:509)<br />
at edu.stanford.smi.protege.model.framestore.ModificationFrameStore.getFrame(ModificationFrameStore.java:26)<br />
at edu.stanford.smi.protege.model.framestore.ArgumentCheckingFrameStore.getFrame(ArgumentCheckingFrameStore.java:107)<br />
</pre><br />
<br />
There are some other things that can go wrong when the client and the server have different versions. In particular another type of error that we saw recently involved a client that used certain remote jobs that the server did not know about. This raised the following exception (seen on the client):<br />
<pre><br />
WARNING: edu.stanford.smi.protege.exception.ProtegeIOException: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: <br />
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: <br />
java.lang.ClassNotFoundException: null class<br />
at edu.stanford.smi.protege.server.framestore.RemoteClientFrameStore.executeProtegeJob(RemoteClientFrameStore.java:1691)<br />
at edu.stanford.smi.protege.util.ProtegeJob.execute(ProtegeJob.java:94)<br />
...<br />
</pre><br />
The key hint here is that the error occurred during executeProtegeJob. The error happened on the server (who is not able to find a class passed to it from the client) and is displayed on the client. This type of exception suggests that the client and server are running different versions of Protege or that the server needs to be running a plugin that is running on the client.<br />
<br />
<br />
= RMI Registry Synchronization =<br />
<br />
Sometime, not very often, a problem arises where the rmiregistry needs to be restarted. So if the client-server has been running fine and you are suddenly having mysterious problems, try killing the rmiregistry and restarting it. I don't know anyone who understands this issue.<br />
<br />
<br />
= Networks, Firewalls and Telnet =<br />
<br />
It is out of scope for the Protege team to diagnose network problems. There are simply too many things that can go wrong and too many things to know. The primary indicator that you need to start thinking about netowrk issues is that the server works fine on localhost or on the lan but not from outside the lan. In this case, telnet is a useful tool for quickly evaluating where a problem is located. All real operating systems with possibly (grudgingly admitted) one exception have a telnet command. If your operating system is under configured you can try this link for [http://www.arsgeek.com/2007/03/20/enable-telnet-in-windows-vista/ enabling telnet] or [http://www.chiark.greenend.org.uk/~sgtatham/putty/]. I haven't tried either but you should also feel free to complain to your vendor for leaving out such a basic diagnostic command.<br />
<br />
What telnet does is to allow you to connect to a hostname and a port. If you know a protocol in detail it is also possible (usually not recommended) to talk a bit with a server this way. For example, using the host www.google.com and port 80 you can try ''GET /''. There are also instructions on various web pages for talking with mail servers, etc. In our case, all we are interested in is whether the client can connect. So depending on your telnet client, a successful connection will look something like this:<br />
<pre><br />
[tredmond@smi-tredmond-li org.protege.osgi.jdbc.prefs]$ telnet smi-tredmond-li 5100<br />
Trying 127.0.1.1...<br />
Connected to smi-tredmond-li.<br />
Escape character is '^]'.<br />
</pre><br />
At this point, with this client, type control-] and then quit and telnet will exit. In the case of a problem, it may take a bit of time for telnet to realize that it cannot connect. In the case that it can connect, it usually connects very quickly.<br />
<br />
There are two connections that need to be tested. The first connection is the connection to the rmiregistry. By default the rmi registry runs on port 1099 but it can be changed when the rmi registry is invoked with the command <br />
<pre><br />
rmiregisty [port #].<br />
</pre><br />
In addition the server is configured to talk to a particular rmiregistry port with the jvm definition <br />
<pre><br />
-Dprotege.rmi.registry.port=[port #].<br />
</pre> <br />
The rmi registry port that the server is using can also be seen in the server console message near the top:<br />
<pre><br />
Server port = 5200, registry port = 5100, compressed stream<br />
</pre><br />
The other connection that needs to be tested is the server connection. The server port can be determined if you have a server reference message in some clients logs:<br />
<pre><br />
Server ref = Server_Stub[UnicastRef2 [liveRef: [endpoint:[67.180.198.51:38547,edu.stanford.smi.protege.server.socket.RmiSocketFactory@2](remote),objID:[-4da377e5:122e64da065:-8000, 0]]]]<br />
</pre><br />
but the easiest way to know the server port is to set it with a jvm definition:<br />
<pre><br />
-Dprotege.rmi.server.port=5200.<br />
</pre><br />
If telnet cannot connect then neither will Protege and the problem is to figure out why the connection failed. This telnet test can be run from different machines on your network to determine exactly what is causing a problem with the network.<br />
<br />
== Configuration ==<br />
To resolve configuration issues arising from NAT firewalls, here's a simple walkthrough that hopefully helps someone. <br />
<br />
* In your Protege client application, edit the "protege.properties" file in the installation directory and add the line (or modify if it already exists), where ''hostname'' is the HOSTNAME (not the domain name) and ''RMI_REG_PORT'' is the RMI Registry Port. By default this is 1099, but can be changed from the server configuration. The global IP Address of the server also works in place of the hostname, but a common mistake is to set this to the local IP address of the server. <br />
edu.stanford.smi.protege.server.ServerPanel.host_name=''hostname''\:''RMI_REG_PORT''<br />
* In your Protege Server installation, make the following changes to "run_protege_server.sh":<br />
** For the HOSTNAME_PARAM variable, replace `hostname` with the actual hostname of your machine (same as specified from the client side so you know its globally-routable). A common mistake is to set this to "localhost" or to a locally routable hostname.<br />
** Add the following lines before the PORTOPTS variable is defined:<br />
RMI_REG_PORT=1099<br />
RMI_SERV_PORT=5200<br />
** Uncomment the line defining the PORTOPTS variable and change it to:<br />
PORTOPTS="-Dprotege.rmi.server.port=$RMI_SERV_PORT -Dprotege.rmi.registry.port=$RMI_REG_PORT"<br />
** Add the RMI_REG_PORT argument to the rmiregistry command, like this:<br />
$JAVA_PATH/rmiregistry $RMI_REG_PORT &<br />
* Make sure you configure your firewall to allow TCP traffic to the RMI_REG_PORT and RMI_SERV_PORT</div>Dustinburkehttps://protegewiki.stanford.edu/index.php?title=Troubleshooting_Client_Server_Connections&diff=7068Troubleshooting Client Server Connections2010-03-05T18:51:54Z<p>Dustinburke: /* Configuration */</p>
<hr />
<div><div class="orangeBox"><br />
<span class="orangeBoxTitle">Client-Server Troubleshooting</span><br /><br /><br />
<br />
'''This page is in the very early stages.'''<br />
<br />
</div><br />
<br />
<br />
__TOC__<br />
<br />
<br />
= Basics =<br />
<br />
In troubleshooting, it is very useful to understand that the client will first connect to the rmi registry to get a reference to the server and then will use the server reference to contact the server.<br />
This protocol is discussed [[Protege_Client_Server_RMI|here]] (ignore the black magic tricks unless they help you get a better understanding).<br />
<br />
The first thing to do is to look at any messages on the client and server console. The most fundamental error that can arise is the following exception which appears on the client console:<br />
<pre><br />
SEVERE: java.rmi.ConnectException: Connection refused to host: localhost; nested exception is: <br />
java.net.ConnectException: Connection refused<br />
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)<br />
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)<br />
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)<br />
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306)<br />
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)<br />
at java.rmi.Naming.lookup(Naming.java:84)<br />
at edu.stanford.smi.protege.server.ServerPanel.connectToHost(ServerPanel.java:140)<br />
</pre><br />
Note that the exception happens when trying to call Naming.lookup. Usually the client will pop up a window that says ''Unable to Connect to Server''. This means that the client could not connect to the rmiregistry. Possibly the rmiregistry is not running or there is a firewall or other network problem.<br />
<br />
An alternate very different error that appears on the client console is the following exception<br />
<pre><br />
SEVERE: java.rmi.ConnectException: Connection refused to host: 67.180.198.51; nested exception is: <br />
java.net.ConnectException: Connection timed out<br />
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)<br />
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)<br />
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)<br />
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:94)<br />
at edu.stanford.smi.protege.server.Server_Stub.openSession(Unknown Source)<br />
at edu.stanford.smi.protege.server.ServerPanel.createSession(ServerPanel.java:154))<br />
</pre><br />
This is usually accompanied by the message ''Failed to create a session because of either an invalid username/password combination, or a firewall problem''. Unfortunately this pop up dialog is very ambiguous and can mean many things. It is for this reason that we have tried to add some additional information to help. In any case the exception tells us two very important things. First the problem occurs during an attempt ot create a session (ServerPanel.createSession) when the client makes a call to the server (Server_Stub.openSession(Unknown Source). In particular, since the client is talking to the server, it means that it has already talked to the rmiregistry to obtain a pointer to the client. That is, this exception means that the client has gotten quite a bit further than it had in the previous case.<br />
<br />
Note that the connection is being refused to the host 67.180.198.51. It is important to look at this because this is often the problem - the connection is being made to the wrong place. There is another message that amplifies on this issue:<br />
<pre><br />
Server ref = Server_Stub[UnicastRef2 [liveRef: [endpoint:[67.180.198.51:38547,edu.stanford.smi.protege.server.socket.RmiSocketFactory@2](remote),objID:[-4da377e5:122e64da065:-8000, 0]]]]<br />
</pre><br />
This is a printout of the server reference that (1) the server passed to the rmiregistry at server startup and (2) the rmiregistry gave to the client to tell it how to contact the server. Not the endpoint:<br />
<pre><br />
67.180.198.51:38547.<br />
</pre><br />
This is the host and port that the rmiregistry thinks should be used to connect to the server. The Connection Refused exception suggests that there is some problem with this.<br />
<br />
One problem that can occur is that the server misrepresents itself when talking to the rmiregistry. At this point it is worth taking a glance at the first few paragraphs of [[Protege_Client_Server_RMI|description of the rmi protocol]]. The server decides how to represent itself to the based on the line:<br />
<pre><br />
-Djava.rmi.server.hostname=`hostname`<br />
</pre><br />
Sometimes this line doesn't do the right thing because the ''hostname'' command returns the wrong value. For instance, perhaps the hostname parameter returns ''smi-tredmond-li'' instead of ''smi-tredmond-li.stanford.edu''. Perhaps, depending on your network configuration, first of these can be resolved by the client and the second cannot. Another thing that the ''hostname'' command sometimes returns is ''localhost'' which will not work for any client on a different machine than the server.<br />
<br />
The client console/log is not the only place to look for hints about a problem. The server console can also have useful information. For example, if I simply supply the wrong user name or password, the server prints out a message<br />
<pre><br />
WARNING: Failed login for user Timothy Redmond IP: 127.0.1.1 -- Server.openSession()<br />
</pre><br />
In addition no server or client-side exceptions are generated.<br />
This means that the client successfully contacted the server, the server successfully processed the request but rejected it because the credentials were wrong.<br />
<br />
<br />
= Versioning Problems and UnmarshalExceptions =<br />
<br />
In order to have a Protege client work reliably with a Protege server, both must be running exactly the same version of Protege. There are several things that can go wrong when the version numbers are different. But the most obvious exception is an UnmarshalException which looks something like the following:<br />
<pre><br />
WARNING: Could not connect to remote project Collaborative Pizza -- java.lang.RuntimeException: java.rmi.UnmarshalException: error unmarshalling return; nested exception is: <br />
java.io.InvalidClassException: edu.stanford.smi.protege.server.update.ValueUpdate; local class incompatible: stream classdesc serialVersionUID = -7753881900765528485, local class serialVersionUID = -4059275656078639103<br />
at edu.stanford.smi.protege.server.framestore.RemoteClientFrameStore.convertException(RemoteClientFrameStore.java:388)<br />
at edu.stanford.smi.protege.server.framestore.RemoteClientFrameStore.getFrame(RemoteClientFrameStore.java:509)<br />
at edu.stanford.smi.protege.model.framestore.ModificationFrameStore.getFrame(ModificationFrameStore.java:26)<br />
at edu.stanford.smi.protege.model.framestore.ArgumentCheckingFrameStore.getFrame(ArgumentCheckingFrameStore.java:107)<br />
</pre><br />
<br />
There are some other things that can go wrong when the client and the server have different versions. In particular another type of error that we saw recently involved a client that used certain remote jobs that the server did not know about. This raised the following exception (seen on the client):<br />
<pre><br />
WARNING: edu.stanford.smi.protege.exception.ProtegeIOException: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: <br />
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: <br />
java.lang.ClassNotFoundException: null class<br />
at edu.stanford.smi.protege.server.framestore.RemoteClientFrameStore.executeProtegeJob(RemoteClientFrameStore.java:1691)<br />
at edu.stanford.smi.protege.util.ProtegeJob.execute(ProtegeJob.java:94)<br />
...<br />
</pre><br />
The key hint here is that the error occurred during executeProtegeJob. The error happened on the server (who is not able to find a class passed to it from the client) and is displayed on the client. This type of exception suggests that the client and server are running different versions of Protege or that the server needs to be running a plugin that is running on the client.<br />
<br />
<br />
= RMI Registry Synchronization =<br />
<br />
Sometime, not very often, a problem arises where the rmiregistry needs to be restarted. So if the client-server has been running fine and you are suddenly having mysterious problems, try killing the rmiregistry and restarting it. I don't know anyone who understands this issue.<br />
<br />
<br />
= Networks, Firewalls and Telnet =<br />
<br />
It is out of scope for the Protege team to diagnose network problems. There are simply too many things that can go wrong and too many things to know. The primary indicator that you need to start thinking about netowrk issues is that the server works fine on localhost or on the lan but not from outside the lan. In this case, telnet is a useful tool for quickly evaluating where a problem is located. All real operating systems with possibly (grudgingly admitted) one exception have a telnet command. If your operating system is under configured you can try this link for [http://www.arsgeek.com/2007/03/20/enable-telnet-in-windows-vista/ enabling telnet] or [http://www.chiark.greenend.org.uk/~sgtatham/putty/]. I haven't tried either but you should also feel free to complain to your vendor for leaving out such a basic diagnostic command.<br />
<br />
What telnet does is to allow you to connect to a hostname and a port. If you know a protocol in detail it is also possible (usually not recommended) to talk a bit with a server this way. For example, using the host www.google.com and port 80 you can try ''GET /''. There are also instructions on various web pages for talking with mail servers, etc. In our case, all we are interested in is whether the client can connect. So depending on your telnet client, a successful connection will look something like this:<br />
<pre><br />
[tredmond@smi-tredmond-li org.protege.osgi.jdbc.prefs]$ telnet smi-tredmond-li 5100<br />
Trying 127.0.1.1...<br />
Connected to smi-tredmond-li.<br />
Escape character is '^]'.<br />
</pre><br />
At this point, with this client, type control-] and then quit and telnet will exit. In the case of a problem, it may take a bit of time for telnet to realize that it cannot connect. In the case that it can connect, it usually connects very quickly.<br />
<br />
There are two connections that need to be tested. The first connection is the connection to the rmiregistry. By default the rmi registry runs on port 1099 but it can be changed when the rmi registry is invoked with the command <br />
<pre><br />
rmiregisty [port #].<br />
</pre><br />
In addition the server is configured to talk to a particular rmiregistry port with the jvm definition <br />
<pre><br />
-Dprotege.rmi.registry.port=[port #].<br />
</pre> <br />
The rmi registry port that the server is using can also be seen in the server console message near the top:<br />
<pre><br />
Server port = 5200, registry port = 5100, compressed stream<br />
</pre><br />
The other connection that needs to be tested is the server connection. The server port can be determined if you have a server reference message in some clients logs:<br />
<pre><br />
Server ref = Server_Stub[UnicastRef2 [liveRef: [endpoint:[67.180.198.51:38547,edu.stanford.smi.protege.server.socket.RmiSocketFactory@2](remote),objID:[-4da377e5:122e64da065:-8000, 0]]]]<br />
</pre><br />
but the easiest way to know the server port is to set it with a jvm definition:<br />
<pre><br />
-Dprotege.rmi.server.port=5200.<br />
</pre><br />
If telnet cannot connect then neither will Protege and the problem is to figure out why the connection failed. This telnet test can be run from different machines on your network to determine exactly what is causing a problem with the network.<br />
<br />
== Configuration ==<br />
To resolve configuration issues arising from NAT firewalls, here's a simple walkthrough that hopefully helps someone. <br />
<br />
# In your Protege client application, edit the "protege.properties" file in the installation directory and add the line (or modify if it already exists), where ''hostname'' is the HOSTNAME (not the domain name) and ''RMI_REG_PORT'' is the RMI Registry Port. By default this is 1099, but can be changed from the server configuration. The global IP Address of the server also works in place of the hostname, but a common mistake is to set this to the local IP address of the server. <br />
edu.stanford.smi.protege.server.ServerPanel.host_name=''hostname''\:''RMI_REG_PORT''<br />
# In your Protege Server installation, make the following changes to "run_protege_server.sh":<br />
#* For the HOSTNAME_PARAM variable, replace `hostname` with the actual hostname of your machine (same as specified from the client side so you know its globally-routable). A common mistake is to set this to "localhost" or to a locally routable hostname.<br />
#* Add the following lines before the PORTOPTS variable is defined:<br />
RMI_REG_PORT=1099<br />
RMI_SERV_PORT=5200<br />
#* Uncomment the line defining the PORTOPTS variable and change it to:<br />
PORTOPTS="-Dprotege.rmi.server.port=$RMI_SERV_PORT -Dprotege.rmi.registry.port=$RMI_REG_PORT"<br />
#* Add the RMI_REG_PORT argument to the rmiregistry command, like this:<br />
$JAVA_PATH/rmiregistry $RMI_REG_PORT &<br />
# Make sure you configure your firewall to allow TCP traffic to the RMI_REG_PORT and RMI_SERV_PORT</div>Dustinburkehttps://protegewiki.stanford.edu/index.php?title=Troubleshooting_Client_Server_Connections&diff=7067Troubleshooting Client Server Connections2010-03-05T18:51:25Z<p>Dustinburke: /* Configuration */</p>
<hr />
<div><div class="orangeBox"><br />
<span class="orangeBoxTitle">Client-Server Troubleshooting</span><br /><br /><br />
<br />
'''This page is in the very early stages.'''<br />
<br />
</div><br />
<br />
<br />
__TOC__<br />
<br />
<br />
= Basics =<br />
<br />
In troubleshooting, it is very useful to understand that the client will first connect to the rmi registry to get a reference to the server and then will use the server reference to contact the server.<br />
This protocol is discussed [[Protege_Client_Server_RMI|here]] (ignore the black magic tricks unless they help you get a better understanding).<br />
<br />
The first thing to do is to look at any messages on the client and server console. The most fundamental error that can arise is the following exception which appears on the client console:<br />
<pre><br />
SEVERE: java.rmi.ConnectException: Connection refused to host: localhost; nested exception is: <br />
java.net.ConnectException: Connection refused<br />
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)<br />
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)<br />
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)<br />
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306)<br />
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)<br />
at java.rmi.Naming.lookup(Naming.java:84)<br />
at edu.stanford.smi.protege.server.ServerPanel.connectToHost(ServerPanel.java:140)<br />
</pre><br />
Note that the exception happens when trying to call Naming.lookup. Usually the client will pop up a window that says ''Unable to Connect to Server''. This means that the client could not connect to the rmiregistry. Possibly the rmiregistry is not running or there is a firewall or other network problem.<br />
<br />
An alternate very different error that appears on the client console is the following exception<br />
<pre><br />
SEVERE: java.rmi.ConnectException: Connection refused to host: 67.180.198.51; nested exception is: <br />
java.net.ConnectException: Connection timed out<br />
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)<br />
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)<br />
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)<br />
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:94)<br />
at edu.stanford.smi.protege.server.Server_Stub.openSession(Unknown Source)<br />
at edu.stanford.smi.protege.server.ServerPanel.createSession(ServerPanel.java:154))<br />
</pre><br />
This is usually accompanied by the message ''Failed to create a session because of either an invalid username/password combination, or a firewall problem''. Unfortunately this pop up dialog is very ambiguous and can mean many things. It is for this reason that we have tried to add some additional information to help. In any case the exception tells us two very important things. First the problem occurs during an attempt ot create a session (ServerPanel.createSession) when the client makes a call to the server (Server_Stub.openSession(Unknown Source). In particular, since the client is talking to the server, it means that it has already talked to the rmiregistry to obtain a pointer to the client. That is, this exception means that the client has gotten quite a bit further than it had in the previous case.<br />
<br />
Note that the connection is being refused to the host 67.180.198.51. It is important to look at this because this is often the problem - the connection is being made to the wrong place. There is another message that amplifies on this issue:<br />
<pre><br />
Server ref = Server_Stub[UnicastRef2 [liveRef: [endpoint:[67.180.198.51:38547,edu.stanford.smi.protege.server.socket.RmiSocketFactory@2](remote),objID:[-4da377e5:122e64da065:-8000, 0]]]]<br />
</pre><br />
This is a printout of the server reference that (1) the server passed to the rmiregistry at server startup and (2) the rmiregistry gave to the client to tell it how to contact the server. Not the endpoint:<br />
<pre><br />
67.180.198.51:38547.<br />
</pre><br />
This is the host and port that the rmiregistry thinks should be used to connect to the server. The Connection Refused exception suggests that there is some problem with this.<br />
<br />
One problem that can occur is that the server misrepresents itself when talking to the rmiregistry. At this point it is worth taking a glance at the first few paragraphs of [[Protege_Client_Server_RMI|description of the rmi protocol]]. The server decides how to represent itself to the based on the line:<br />
<pre><br />
-Djava.rmi.server.hostname=`hostname`<br />
</pre><br />
Sometimes this line doesn't do the right thing because the ''hostname'' command returns the wrong value. For instance, perhaps the hostname parameter returns ''smi-tredmond-li'' instead of ''smi-tredmond-li.stanford.edu''. Perhaps, depending on your network configuration, first of these can be resolved by the client and the second cannot. Another thing that the ''hostname'' command sometimes returns is ''localhost'' which will not work for any client on a different machine than the server.<br />
<br />
The client console/log is not the only place to look for hints about a problem. The server console can also have useful information. For example, if I simply supply the wrong user name or password, the server prints out a message<br />
<pre><br />
WARNING: Failed login for user Timothy Redmond IP: 127.0.1.1 -- Server.openSession()<br />
</pre><br />
In addition no server or client-side exceptions are generated.<br />
This means that the client successfully contacted the server, the server successfully processed the request but rejected it because the credentials were wrong.<br />
<br />
<br />
= Versioning Problems and UnmarshalExceptions =<br />
<br />
In order to have a Protege client work reliably with a Protege server, both must be running exactly the same version of Protege. There are several things that can go wrong when the version numbers are different. But the most obvious exception is an UnmarshalException which looks something like the following:<br />
<pre><br />
WARNING: Could not connect to remote project Collaborative Pizza -- java.lang.RuntimeException: java.rmi.UnmarshalException: error unmarshalling return; nested exception is: <br />
java.io.InvalidClassException: edu.stanford.smi.protege.server.update.ValueUpdate; local class incompatible: stream classdesc serialVersionUID = -7753881900765528485, local class serialVersionUID = -4059275656078639103<br />
at edu.stanford.smi.protege.server.framestore.RemoteClientFrameStore.convertException(RemoteClientFrameStore.java:388)<br />
at edu.stanford.smi.protege.server.framestore.RemoteClientFrameStore.getFrame(RemoteClientFrameStore.java:509)<br />
at edu.stanford.smi.protege.model.framestore.ModificationFrameStore.getFrame(ModificationFrameStore.java:26)<br />
at edu.stanford.smi.protege.model.framestore.ArgumentCheckingFrameStore.getFrame(ArgumentCheckingFrameStore.java:107)<br />
</pre><br />
<br />
There are some other things that can go wrong when the client and the server have different versions. In particular another type of error that we saw recently involved a client that used certain remote jobs that the server did not know about. This raised the following exception (seen on the client):<br />
<pre><br />
WARNING: edu.stanford.smi.protege.exception.ProtegeIOException: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: <br />
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: <br />
java.lang.ClassNotFoundException: null class<br />
at edu.stanford.smi.protege.server.framestore.RemoteClientFrameStore.executeProtegeJob(RemoteClientFrameStore.java:1691)<br />
at edu.stanford.smi.protege.util.ProtegeJob.execute(ProtegeJob.java:94)<br />
...<br />
</pre><br />
The key hint here is that the error occurred during executeProtegeJob. The error happened on the server (who is not able to find a class passed to it from the client) and is displayed on the client. This type of exception suggests that the client and server are running different versions of Protege or that the server needs to be running a plugin that is running on the client.<br />
<br />
<br />
= RMI Registry Synchronization =<br />
<br />
Sometime, not very often, a problem arises where the rmiregistry needs to be restarted. So if the client-server has been running fine and you are suddenly having mysterious problems, try killing the rmiregistry and restarting it. I don't know anyone who understands this issue.<br />
<br />
<br />
= Networks, Firewalls and Telnet =<br />
<br />
It is out of scope for the Protege team to diagnose network problems. There are simply too many things that can go wrong and too many things to know. The primary indicator that you need to start thinking about netowrk issues is that the server works fine on localhost or on the lan but not from outside the lan. In this case, telnet is a useful tool for quickly evaluating where a problem is located. All real operating systems with possibly (grudgingly admitted) one exception have a telnet command. If your operating system is under configured you can try this link for [http://www.arsgeek.com/2007/03/20/enable-telnet-in-windows-vista/ enabling telnet] or [http://www.chiark.greenend.org.uk/~sgtatham/putty/]. I haven't tried either but you should also feel free to complain to your vendor for leaving out such a basic diagnostic command.<br />
<br />
What telnet does is to allow you to connect to a hostname and a port. If you know a protocol in detail it is also possible (usually not recommended) to talk a bit with a server this way. For example, using the host www.google.com and port 80 you can try ''GET /''. There are also instructions on various web pages for talking with mail servers, etc. In our case, all we are interested in is whether the client can connect. So depending on your telnet client, a successful connection will look something like this:<br />
<pre><br />
[tredmond@smi-tredmond-li org.protege.osgi.jdbc.prefs]$ telnet smi-tredmond-li 5100<br />
Trying 127.0.1.1...<br />
Connected to smi-tredmond-li.<br />
Escape character is '^]'.<br />
</pre><br />
At this point, with this client, type control-] and then quit and telnet will exit. In the case of a problem, it may take a bit of time for telnet to realize that it cannot connect. In the case that it can connect, it usually connects very quickly.<br />
<br />
There are two connections that need to be tested. The first connection is the connection to the rmiregistry. By default the rmi registry runs on port 1099 but it can be changed when the rmi registry is invoked with the command <br />
<pre><br />
rmiregisty [port #].<br />
</pre><br />
In addition the server is configured to talk to a particular rmiregistry port with the jvm definition <br />
<pre><br />
-Dprotege.rmi.registry.port=[port #].<br />
</pre> <br />
The rmi registry port that the server is using can also be seen in the server console message near the top:<br />
<pre><br />
Server port = 5200, registry port = 5100, compressed stream<br />
</pre><br />
The other connection that needs to be tested is the server connection. The server port can be determined if you have a server reference message in some clients logs:<br />
<pre><br />
Server ref = Server_Stub[UnicastRef2 [liveRef: [endpoint:[67.180.198.51:38547,edu.stanford.smi.protege.server.socket.RmiSocketFactory@2](remote),objID:[-4da377e5:122e64da065:-8000, 0]]]]<br />
</pre><br />
but the easiest way to know the server port is to set it with a jvm definition:<br />
<pre><br />
-Dprotege.rmi.server.port=5200.<br />
</pre><br />
If telnet cannot connect then neither will Protege and the problem is to figure out why the connection failed. This telnet test can be run from different machines on your network to determine exactly what is causing a problem with the network.<br />
<br />
== Configuration ==<br />
To resolve configuration issues arising from NAT firewalls, here's a simple walkthrough that hopefully helps someone. <br />
<br />
# In your Protege client application, edit the "protege.properties" file in the installation directory and add the line (or modify if it already exists), where ''hostname'' is the HOSTNAME (not the domain name) and ''RMI_REG_PORT'' is the RMI Registry Port. By default this is 1099, but can be changed from the server configuration. The global IP Address of the server also works in place of the hostname, but a common mistake is to set this to the local IP address of the server. <br />
#: edu.stanford.smi.protege.server.ServerPanel.host_name=''hostname''\:''RMI_REG_PORT''<br />
# In your Protege Server installation, make the following changes to "run_protege_server.sh":<br />
#* For the HOSTNAME_PARAM variable, replace `hostname` with the actual hostname of your machine (same as specified from the client side so you know its globally-routable). A common mistake is to set this to "localhost" or to a locally routable hostname.<br />
#* Add the following lines before the PORTOPTS variable is defined:<br />
#*: RMI_REG_PORT=1099<br />
#*: RMI_SERV_PORT=5200<br />
#* Uncomment the line defining the PORTOPTS variable and change it to:<br />
#*: PORTOPTS="-Dprotege.rmi.server.port=$RMI_SERV_PORT -Dprotege.rmi.registry.port=$RMI_REG_PORT"<br />
#* Add the RMI_REG_PORT argument to the rmiregistry command, like this:<br />
#*: $JAVA_PATH/rmiregistry $RMI_REG_PORT &<br />
# Make sure you configure your firewall to allow TCP traffic to the RMI_REG_PORT and RMI_SERV_PORT</div>Dustinburkehttps://protegewiki.stanford.edu/index.php?title=Troubleshooting_Client_Server_Connections&diff=7066Troubleshooting Client Server Connections2010-03-05T18:50:44Z<p>Dustinburke: /* Networks, Firewalls and Telnet */</p>
<hr />
<div><div class="orangeBox"><br />
<span class="orangeBoxTitle">Client-Server Troubleshooting</span><br /><br /><br />
<br />
'''This page is in the very early stages.'''<br />
<br />
</div><br />
<br />
<br />
__TOC__<br />
<br />
<br />
= Basics =<br />
<br />
In troubleshooting, it is very useful to understand that the client will first connect to the rmi registry to get a reference to the server and then will use the server reference to contact the server.<br />
This protocol is discussed [[Protege_Client_Server_RMI|here]] (ignore the black magic tricks unless they help you get a better understanding).<br />
<br />
The first thing to do is to look at any messages on the client and server console. The most fundamental error that can arise is the following exception which appears on the client console:<br />
<pre><br />
SEVERE: java.rmi.ConnectException: Connection refused to host: localhost; nested exception is: <br />
java.net.ConnectException: Connection refused<br />
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)<br />
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)<br />
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)<br />
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306)<br />
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)<br />
at java.rmi.Naming.lookup(Naming.java:84)<br />
at edu.stanford.smi.protege.server.ServerPanel.connectToHost(ServerPanel.java:140)<br />
</pre><br />
Note that the exception happens when trying to call Naming.lookup. Usually the client will pop up a window that says ''Unable to Connect to Server''. This means that the client could not connect to the rmiregistry. Possibly the rmiregistry is not running or there is a firewall or other network problem.<br />
<br />
An alternate very different error that appears on the client console is the following exception<br />
<pre><br />
SEVERE: java.rmi.ConnectException: Connection refused to host: 67.180.198.51; nested exception is: <br />
java.net.ConnectException: Connection timed out<br />
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)<br />
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)<br />
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)<br />
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:94)<br />
at edu.stanford.smi.protege.server.Server_Stub.openSession(Unknown Source)<br />
at edu.stanford.smi.protege.server.ServerPanel.createSession(ServerPanel.java:154))<br />
</pre><br />
This is usually accompanied by the message ''Failed to create a session because of either an invalid username/password combination, or a firewall problem''. Unfortunately this pop up dialog is very ambiguous and can mean many things. It is for this reason that we have tried to add some additional information to help. In any case the exception tells us two very important things. First the problem occurs during an attempt ot create a session (ServerPanel.createSession) when the client makes a call to the server (Server_Stub.openSession(Unknown Source). In particular, since the client is talking to the server, it means that it has already talked to the rmiregistry to obtain a pointer to the client. That is, this exception means that the client has gotten quite a bit further than it had in the previous case.<br />
<br />
Note that the connection is being refused to the host 67.180.198.51. It is important to look at this because this is often the problem - the connection is being made to the wrong place. There is another message that amplifies on this issue:<br />
<pre><br />
Server ref = Server_Stub[UnicastRef2 [liveRef: [endpoint:[67.180.198.51:38547,edu.stanford.smi.protege.server.socket.RmiSocketFactory@2](remote),objID:[-4da377e5:122e64da065:-8000, 0]]]]<br />
</pre><br />
This is a printout of the server reference that (1) the server passed to the rmiregistry at server startup and (2) the rmiregistry gave to the client to tell it how to contact the server. Not the endpoint:<br />
<pre><br />
67.180.198.51:38547.<br />
</pre><br />
This is the host and port that the rmiregistry thinks should be used to connect to the server. The Connection Refused exception suggests that there is some problem with this.<br />
<br />
One problem that can occur is that the server misrepresents itself when talking to the rmiregistry. At this point it is worth taking a glance at the first few paragraphs of [[Protege_Client_Server_RMI|description of the rmi protocol]]. The server decides how to represent itself to the based on the line:<br />
<pre><br />
-Djava.rmi.server.hostname=`hostname`<br />
</pre><br />
Sometimes this line doesn't do the right thing because the ''hostname'' command returns the wrong value. For instance, perhaps the hostname parameter returns ''smi-tredmond-li'' instead of ''smi-tredmond-li.stanford.edu''. Perhaps, depending on your network configuration, first of these can be resolved by the client and the second cannot. Another thing that the ''hostname'' command sometimes returns is ''localhost'' which will not work for any client on a different machine than the server.<br />
<br />
The client console/log is not the only place to look for hints about a problem. The server console can also have useful information. For example, if I simply supply the wrong user name or password, the server prints out a message<br />
<pre><br />
WARNING: Failed login for user Timothy Redmond IP: 127.0.1.1 -- Server.openSession()<br />
</pre><br />
In addition no server or client-side exceptions are generated.<br />
This means that the client successfully contacted the server, the server successfully processed the request but rejected it because the credentials were wrong.<br />
<br />
<br />
= Versioning Problems and UnmarshalExceptions =<br />
<br />
In order to have a Protege client work reliably with a Protege server, both must be running exactly the same version of Protege. There are several things that can go wrong when the version numbers are different. But the most obvious exception is an UnmarshalException which looks something like the following:<br />
<pre><br />
WARNING: Could not connect to remote project Collaborative Pizza -- java.lang.RuntimeException: java.rmi.UnmarshalException: error unmarshalling return; nested exception is: <br />
java.io.InvalidClassException: edu.stanford.smi.protege.server.update.ValueUpdate; local class incompatible: stream classdesc serialVersionUID = -7753881900765528485, local class serialVersionUID = -4059275656078639103<br />
at edu.stanford.smi.protege.server.framestore.RemoteClientFrameStore.convertException(RemoteClientFrameStore.java:388)<br />
at edu.stanford.smi.protege.server.framestore.RemoteClientFrameStore.getFrame(RemoteClientFrameStore.java:509)<br />
at edu.stanford.smi.protege.model.framestore.ModificationFrameStore.getFrame(ModificationFrameStore.java:26)<br />
at edu.stanford.smi.protege.model.framestore.ArgumentCheckingFrameStore.getFrame(ArgumentCheckingFrameStore.java:107)<br />
</pre><br />
<br />
There are some other things that can go wrong when the client and the server have different versions. In particular another type of error that we saw recently involved a client that used certain remote jobs that the server did not know about. This raised the following exception (seen on the client):<br />
<pre><br />
WARNING: edu.stanford.smi.protege.exception.ProtegeIOException: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: <br />
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: <br />
java.lang.ClassNotFoundException: null class<br />
at edu.stanford.smi.protege.server.framestore.RemoteClientFrameStore.executeProtegeJob(RemoteClientFrameStore.java:1691)<br />
at edu.stanford.smi.protege.util.ProtegeJob.execute(ProtegeJob.java:94)<br />
...<br />
</pre><br />
The key hint here is that the error occurred during executeProtegeJob. The error happened on the server (who is not able to find a class passed to it from the client) and is displayed on the client. This type of exception suggests that the client and server are running different versions of Protege or that the server needs to be running a plugin that is running on the client.<br />
<br />
<br />
= RMI Registry Synchronization =<br />
<br />
Sometime, not very often, a problem arises where the rmiregistry needs to be restarted. So if the client-server has been running fine and you are suddenly having mysterious problems, try killing the rmiregistry and restarting it. I don't know anyone who understands this issue.<br />
<br />
<br />
= Networks, Firewalls and Telnet =<br />
<br />
It is out of scope for the Protege team to diagnose network problems. There are simply too many things that can go wrong and too many things to know. The primary indicator that you need to start thinking about netowrk issues is that the server works fine on localhost or on the lan but not from outside the lan. In this case, telnet is a useful tool for quickly evaluating where a problem is located. All real operating systems with possibly (grudgingly admitted) one exception have a telnet command. If your operating system is under configured you can try this link for [http://www.arsgeek.com/2007/03/20/enable-telnet-in-windows-vista/ enabling telnet] or [http://www.chiark.greenend.org.uk/~sgtatham/putty/]. I haven't tried either but you should also feel free to complain to your vendor for leaving out such a basic diagnostic command.<br />
<br />
What telnet does is to allow you to connect to a hostname and a port. If you know a protocol in detail it is also possible (usually not recommended) to talk a bit with a server this way. For example, using the host www.google.com and port 80 you can try ''GET /''. There are also instructions on various web pages for talking with mail servers, etc. In our case, all we are interested in is whether the client can connect. So depending on your telnet client, a successful connection will look something like this:<br />
<pre><br />
[tredmond@smi-tredmond-li org.protege.osgi.jdbc.prefs]$ telnet smi-tredmond-li 5100<br />
Trying 127.0.1.1...<br />
Connected to smi-tredmond-li.<br />
Escape character is '^]'.<br />
</pre><br />
At this point, with this client, type control-] and then quit and telnet will exit. In the case of a problem, it may take a bit of time for telnet to realize that it cannot connect. In the case that it can connect, it usually connects very quickly.<br />
<br />
There are two connections that need to be tested. The first connection is the connection to the rmiregistry. By default the rmi registry runs on port 1099 but it can be changed when the rmi registry is invoked with the command <br />
<pre><br />
rmiregisty [port #].<br />
</pre><br />
In addition the server is configured to talk to a particular rmiregistry port with the jvm definition <br />
<pre><br />
-Dprotege.rmi.registry.port=[port #].<br />
</pre> <br />
The rmi registry port that the server is using can also be seen in the server console message near the top:<br />
<pre><br />
Server port = 5200, registry port = 5100, compressed stream<br />
</pre><br />
The other connection that needs to be tested is the server connection. The server port can be determined if you have a server reference message in some clients logs:<br />
<pre><br />
Server ref = Server_Stub[UnicastRef2 [liveRef: [endpoint:[67.180.198.51:38547,edu.stanford.smi.protege.server.socket.RmiSocketFactory@2](remote),objID:[-4da377e5:122e64da065:-8000, 0]]]]<br />
</pre><br />
but the easiest way to know the server port is to set it with a jvm definition:<br />
<pre><br />
-Dprotege.rmi.server.port=5200.<br />
</pre><br />
If telnet cannot connect then neither will Protege and the problem is to figure out why the connection failed. This telnet test can be run from different machines on your network to determine exactly what is causing a problem with the network.<br />
<br />
== Configuration ==<br />
To resolve configuration issues arising from NAT firewalls, here's a simple walkthrough that hopefully helps someone. <br />
<br />
# In your Protege client application, edit the "protege.properties" file in the installation directory and add the line (or modify if it already exists):<br />
#: edu.stanford.smi.protege.server.ServerPanel.host_name=''hostname''\:''RMI_REG_PORT''<br />
#: where ''hostname'' is the HOSTNAME (not the domain name) and ''RMI_REG_PORT'' is the RMI Registry Port. By default this is 1099, but can be changed from the server configuration. The global IP Address of the server also works in place of the hostname, but a common mistake is to set this to the local IP address of the server. <br />
# In your Protege Server installation, make the following changes to "run_protege_server.sh":<br />
#* For the HOSTNAME_PARAM variable, replace `hostname` with the actual hostname of your machine (same as specified from the client side so you know its globally-routable). A common mistake is to set this to "localhost" or to a locally routable hostname.<br />
#* Add the following lines before the PORTOPTS variable is defined:<br />
#*: RMI_REG_PORT=1099<br />
#*: RMI_SERV_PORT=5200<br />
#* Uncomment the line defining the PORTOPTS variable and change it to:<br />
#*: PORTOPTS="-Dprotege.rmi.server.port=$RMI_SERV_PORT -Dprotege.rmi.registry.port=$RMI_REG_PORT"<br />
#* Add the RMI_REG_PORT argument to the rmiregistry command, like this:<br />
#*: $JAVA_PATH/rmiregistry $RMI_REG_PORT &<br />
# Make sure you configure your firewall to allow TCP traffic to the RMI_REG_PORT and RMI_SERV_PORT</div>Dustinburke