Other Notes
- As documented in the main
P4 Server
documentation,
P4 Server
form triggers can cause additional output on form commands such as
“change” or “client”, even when the trigger succeeds. This trigger
output is available through the P4 API for Java command callback feature, but
note that there is currently no way to differentiate trigger output
from normal command output, and that such trigger output will also be
prepended or appended to normal string output on commands such as
IOptionsServer.newLabel. - P4 API for Java’s command callback feature, documented in class
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 thep4command line client’s output. Usage is straightforward, but note the potential for deadlocks and blocking if you are not careful with callback method implementation. - P4 API for Java’s progress callback feature gives users a somewhat
impressionistic measure of command progress for longer-running
commands. Progress callbacks are documented in the Javadoc for class
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
progNameandprogVersionproperties (either globally or for eachIOptionsServerinstance) whenever you use P4 API for Java. Set these values to something meaningful that reflects the application or tool in which P4 API for Java is embedded; this can help P4 Server administrators and application debugging.For example, the following code sets
progNameandprogVersionvia 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
getServermethod’s properties parameter:CopyProperties props = new Properties(System.getProperties());
props.setProperty(PropertyDefs.PROG_NAME_KEY, "ant-test");
props.setProperty(PropertyDefs.PROG_VERSION_KEY, "Alpha 0.9d");
...
server = IOptionServerFactory.getServer(serverUriString, props);
-
If your application receives a
ConnectionExceptionfrom anIOptionsServerorIClientmethod while communicating with a P4 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
ConnectionExceptionevent typically represents a serious network error (such as the P4 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
IFileSpecinterfaces to compare versions of the same P4 Server-managed file, but this functionality may be easily implemented with a combination ofIOptionsServer.getFileContentsto 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:CopyInputStream 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();
}