If you are in a multi-node environment you will need to restart all the nodes. Otherwise the library may be in the database but not yet be part of the 'classpath' of the node on which you are configuring your Library import statements.
Check the logs after startup to verify that the codeset you used when importing the JAR is referenced in the log messages written during startup.
Posted: 3 days ago
Updated: 3 days ago
Posted: 17 Jan 2021 20:35 EST Updated: 17 Jan 2021 20:36 EST
Firstly be sure that your PDF library supports what you are trying to achieve. The 'static' strings you included first above are paths to PDF documents on a file system; but you then suggest that Doc.pyNote is the (encoded) PDF content. I doubt the PdfReader(String) and PdfWriter(String) constructors can magically determine whether your String is a filename or file content. Be sure that the classes in the PDF library you are using are expecting content, not paths. That's up to you and your usage of the library, though.
From the point of view of the Pega Java API, I expect that Doc.pyNote is a clipboard reference, not a parameter. That is, your intent is to read the Base64 encoded PDF content from Doc.pyNote, transform it, then write it back to the same property on the clipboard.
Best Practice when coding Java in Pega is to implement the Java code in a Function rule, which is associated with a Library rule. Your earlier screenshots showing the Library ruleform suggest you were heading down this path, but the use of 'tools' in your latest code sample suggests you might now be trying a Java step in an Activity. Revert back to the Function/Library approach. If you are getting fully-qualified references to your library classes to compile now, perhaps the import issues you were having with the Library ruleform earlier are resolved.
The advantage of the Function rule (over a Java step in an Activity) is that you can define your Function to take a parameter of type ClipboardProperty, allowing your Function to interact with that property without intricate references to 'tools' and also avoiding hardcoding a particular property on a particular page into your Java code.
Assuming your Function was named transformPdf, and had a parameter named pdfContentProperty of type ClipboardProperty, your Function would look something like this:
// 1. Get the Base64-encoded PDF content from the (Text) clipboard property
String originalContent = pdfContentProperty.getStringValue();
// 2. Initialize PdfDocument instance using 'originalContent' as input
// 3. Perform transformations on PdfDocument
// 4. Get Base64-encoded content from PdfDocument instance after transformation
String transformedContent = ...
// 5. Set the clipboard property to hold the encoded content after transformation
... then in the use case that has the Doc.pyNote property prepared with the source PDF, the Function call would be:
This Function is reusable in other use cases where a different property on a different clipboard page needs the same transformation. Just call the function and pass the reference to the clipboard property in for its parameter.
For an out of the box example of how to use ClipboardProperty parameters in Function rules, search for PropertyHasValue and pick the result that references ClipboardProperty in its signature.
Javadoc for the classes in Pega's Public API - including the ClipboardProperty class - is available from the Engine API option on Dev Studio's Help menu:
Well, i see. So PDF library its need path for value. But, according to my need, user upload their PDF, and the system will add some text and generate the PDF again, so its may be difficult if every PDF that user uploaded must be located at server.
See whether there are APIs in your PDF library that work with instances of InputStream and OutputStream instead of File. If not, seek a Library that does.
Using Java's ByteArrayInputStream and ByteArrayOutputStream classes are techniques to marshall text in-memory in and out of APIs that can work with Streams of data and not have a dependency on the file system. A file system dependency adds effort for you in terms of clean-up and filename uniqueness across concurrent access, and is less Cloud-friendly than an in-memory design.