IServer.newLabel
.com.perforce.p4java.server.callback.ICommandCallback
, is a
useful way to get blow-by-blow command status messages and trigger
output messages from the server in a way that can mimic the
p4
command line client’s output. Usage is
straightforward, but note the potential for deadlocks and blocking if
you are not careful with callback method implementation.com.perforce.p4java.server.callback.IProgressCallback
.
Once again, if you use this feature, ensure that your callback
implementations do not cause deadlocks or blocking.We strongly recommend setting the progName
and
progVersion
properties (either globally or for each
IServer
instance) whenever you use P4Java. Set these
values to something meaningful that reflects the application or tool
in which P4Java is embedded; this can help
Helix Server
administrators and application debugging.
For example, the following code sets progName
and
progVersion
via the JVM invocation property flags:
$ java -Dcom.perforce.p4java.programName=p4test
-Dcom.perforce.p4java.programVersion=2.01A ...
Alternatively, you can also use the server factory getServer method’s properties parameter:
Properties props = new Properties(System.getProperties());
props.setProperty(PropertyDefs.PROG_NAME_KEY, "ant-test");
props.setProperty(PropertyDefs.PROG_VERSION_KEY, "Alpha 0.9d");
...
server = IServerFactory.getServer(serverUriString, props);
If your application receives a ConnectionException
from
a IServer
or IClient
method while
communicating with a Helix Server, the only truly safe action is to close the connection and
start over with a new connection, rather than continue using the
connection.
A ConnectionException
event typically represents a
serious network error (such as the Helix Server unexpectedly closing a connection or a bad checksum in a
network packet), and there’s no guarantee that after receiving such
an event the connection is even usable, let alone reliable.
There is currently no diff method on IFileSpec
interfaces to compare versions of the same
Helix Server-managed file, but
this functionality may be easily implemented with a combination of
IServer.getFileContents
to retrieve the contents of
specific versions to temporary files, and the use of the operating
system’s diff application on these temporary files as shown
below:
InputStream fspecStream1 = server.getFileContents(
FileSpecBuilder.makeFileSpecList(
new String[] {spec1}), false, true);
InputStream fspecStream2 = server.getFileContents(
FileSpecBuilder.makeFileSpecList(
new String[] {spec2}), false, true);
File file1 = null;
File file2 = null;
try {
file1 = File.createTempFile("p4jdiff", ".tmp");
file2 = File.createTempFile("p4jdiff", ".tmp");
FileOutputStream outStream1 = new FileOutputStream(file1);
FileOutputStream outStream2 = new FileOutputStream(file2);
byte[] bytes = new byte[1024];
int bytesRead = 0;
while bytesRead = fspecStream1.read(bytes > 0) {
outStream1.write(bytes, 0, bytesRead);
}
fspecStream1.close();
outStream1.close();
while bytesRead = fspecStream2.read(bytes > 0) {
outStream2.write(bytes, 0, bytesRead);
}
fspecStream2.close();
outStream2.close();
Process diffProc = Runtime.getRuntime().exec(new String[] {
"/usr/bin/diff",file1.getPath(),file2.getPath()});
diffProc.waitFor();
if (diffProc != null) {
InputStream iStream = diffProc.getInputStream();
byte[] inBytes = new byte[1024];
int inBytesRead = 0;
while inBytesRead = iStream.read(inBytes > 0) {
System.out.write(inBytes, 0, inBytesRead);
}
}
} catch (Exception exc) {
error("diff error: " + exc.getLocalizedMessage());
return;
} finally {
if (file1 != null) file1.delete();
if (file2 != null) file2.delete();
}