Forum How do I...?

Prince 9 on Web Server?

jimbrooking
I've been using Prince 8 for three applications that require hardcopy from information stored on my site's database. PHP code generates XHTML files from the database. (The existing applications use no JavaScript.)

I have installed Prince 9 on my desktop, and it functions well, subject to some earlier comments about usability of the GUI.

I installed Prince 9 on my apache server (run by hostmonster.com) by downloading a 64-bit generic linux file prince-9.0r4-linux-amd64.tar.gz.

Since I can not run scripts on my hostmonster server, I unzipped the file and FTP'd it to /usr/lib/prince9; the Prince 8 install is in /usr/lib/prince.

Whenever I invoke Prince 9 (using the Prince 9 Class definition here: http://www.princexml.com/download/prince-php5-r13.zip, the application terminates immediately with no output. I did notice that permissions on /usr/lib/prince/bin/prince were 644, and changed them manually to 755 with no change in behavior. So:

  • Am I using the correct binary? I can't tell anythng about what linux hostmonster.com uses, but PHP is configursd for 64 bits so I assumed 64 was correct.
  • What other gotchas might be lurking in permissions to cause this? I can't see any logs that tell me why Prince 9 isn't firing and/or is quitting immediately.

    Thank you.

mikeday
If you don't have any shell access to the machine it does make it more difficult to figure out what is going on. If Prince 8 runs, then installing the equivalent Prince 9 package should work.

Normally Prince has a short shell script installed at /usr/bin/prince which execs the binary at /usr/lib/prince/bin/prince. Are you using this mechanism for Prince 8, or calling the binary directly?
jimbrooking
I was calling the executable directly but changed to call the short script. It looks like this short script is created by install.sh. I don't do shell programming but it looks like the extant shell script "prince" as it would be created by the installer would be identical for Prince 8 and Prince 9 and looks like this:
#! /bin/sh
PROGRAM="prince"
prefix=/home1/fearrin1/usr
exec $prefix/lib/$PROGRAM/bin/$PROGRAM --prefix="$prefix/lib/$PROGRAM" "$@"

Is that correct?

This program is in /usr. The PHP that instantiates Prince through the Prince PHP class is
$prince = new Prince('/home1/fearrin1/usr/prince');
if (!$prince)
    die("<p>Prince instantiation failed</p>");


Other calls to $prince methods include
  • $prince->addStyleSheet($css); // called several times to add style sheets
  • $prince->setLog($outLog);
  • $prince->setJavaScript(TRUE); // Enable JavaScript (since Prince v8)
  • $pcvar = $prince->convert_file($outDest,$princeMsgs);
    if(!$pcver) {
    display $princeMsgs and quit
    }
    else {
    provide link to generated PDF
    }
Running this with Prince 9 shows the following as $princeMsgs:
=NULL(0)NULL

which appears immediately after the $prince->convert_file() call, instead of the usual half-minute or more delay with Prince 8.

So I'm concluding that something is preventing the conversion from kicking off, maybe a permissions problem, maybe something else.
mikeday
Right. Can you upload a shell script that calls the binary in a subshell and captures standard error to a file, so you can download the file and see exactly what the problem is?
jimbrooking
I am not unixy enough to know how to do that but will look around and see if I can find something. Never heard of a subshell.
mikeday
Actually it might be as easy as a script like this:
#! /bin/sh

/usr/lib/prince/bin/prince --version 1>/tmp/out 2>/tmp/err

Assuming the /tmp directory is writable (substitute another directory if not) and the path to the Prince binary is correct, this redirects the normal output and error output to two different files so that you can examine them.

Perhaps you could do something similar with the PHP system() function?

Edited by mikeday

jimbrooking
Mike,

Thanks for your patience. Here's what I did:

First, create a file like your sample, in /usr/tpr, permissions 755 containing:
#! /bin/sh
    
/usr/lib/prince9/bin/prince --version 1>/home1/fearrin1/tmp/out.pr.log 2>/home1/fearrin1/tmp/err.pr.log


Next create empty files /tmp/out.pr.log and /tmp/err.pr.log, permisions 666.

Then crib from prince.php to create in my website directory pperr.php containing
<?php

$pathAndArgs = "/home1/fearrin1/usr/" + 'tpr';
$descriptorspec = array(
    0 => array("pipe", "r"),
    1 => array("pipe", "w"),
    2 => array("pipe", "w")
);

echo('<p>starting</p>');

$process = proc_open($pathAndArgs, $descriptorspec, $pipes);

if (is_resource($process)) {
    //  fwrite($pipes[0], $xmlString);
    fclose($pipes[0]);
    fclose($pipes[1]);

    //  $result = $this->readMessages($pipes[2], $msgs);

    fclose($pipes[2]);

    proc_close($process);

    echo('<h1>success</h1>');
} else {
    echo("<h1>Failed to execute $pathAndArgs</h1>");
}

Then load the web page http://www.fearringtonfha.org/pperr.php, the result of which is
starting

success


Examining the files err.pr.log and out.pr.log, I find both are empty. Does Prince (as called in the shell script) require some input?
mikeday
What if you just call it using system("/home1/fearrin1/usr/tpr") instead of proc_open, and add some echo lines in the script to check the files are writable, eg.
echo before > /home1/fearrin1/tmp/out.pr.log
/usr/lib/prince9/bin/prince --version 1>>/home1/fearrin1/tmp/out.pr.log 2>/home1/fearrin1/tmp/err.pr.log
echo after >> /home1/fearrin1/tmp/out.pr.log

(Note the >> instead of >, to append to the file instead of replacing it).
jimbrooking
So this
    echo before > /home1/fearrin1/tmp/out.pr.log
    echo after >> /home1/fearrin1/tmp/err.pr.log
    /home1/fearrin1/usr/lib/prince9/bin/prince --version 1>>/home1/fearrin1/tmp/out.pr.log 2>/home1/fearrin1/tmp/err.pr.log
    echo after >> /home1/fearrin1/tmp/out.pr.log
    echo after >> /home1/fearrin1/tmp/err.pr.log


produced this in err.pr.log:
/home1/fearrin1/usr/lib/prince9/bin/prince: error while loading shared libraries: libtiff.so.4: cannot open shared object file: No such file or directory

What does that mean? Something didn't get loaded/installed properly?

Thanks.
mikeday
Excellent, that's the feedback we need. Prince uses libtiff to load TIFF images. It indicates that the expected version of libtiff is not installed on the server. You could try installing the statically linked Prince package (prince-9.0r4-linux-amd64-static.tar.gz) which includes all the necessary libraries.
jimbrooking
Sincerest gratitude for your perseverance, Mike. Installing the static version worked perfectly, and even seemed to run substantially faster than Prince 8 for the same file.

Thanks again. Prince is a jewel of a program,
mikeday
Great! Glad to hear it's working now.