Concurrent PsDocument.saveAsPdf() Fails with

if the following part runs in parallel

            ByteArrayOutputStream pdfStream = new ByteArrayOutputStream();
            PsDocument document = new PsDocument(officeStream);
            boolean suppressErrors = false;
            PdfSaveOptions options = new PdfSaveOptions(suppressErrors);
            document.saveAsPdf(pdfStream, options);

with bigger postscript files, in some cases we get the following exception:

Caused by: java.lang.NullPointerException: Cannot invoke "com.aspose.page.internal.l1l.I561.lif(String)" because "<parameter3>" is null
	at com.aspose.page.internal.l1l.I377.lif(Unknown Source)
	at com.aspose.page.internal.l1l.I237.lif(Unknown Source)
	at com.aspose.page.internal.l1l.I607.lIF(Unknown Source)
	at com.aspose.page.internal.l1l.I667.ll(Unknown Source)
	at com.aspose.page.internal.l1l.I667.ll(Unknown Source)
	at com.aspose.page.internal.l1l.I667.lI(Unknown Source)
	at com.aspose.eps.PsDocument.ll(Unknown Source)
	at com.aspose.eps.PsDocument.lif(Unknown Source)
	at com.aspose.eps.PsDocument.lif(Unknown Source)
	at com.aspose.eps.PsDocument.save(Unknown Source)
	at com.aspose.eps.PsDocument.saveAsPdf(Unknown Source)

The issue also exists in the latest version 26.8

@stud0r

What do you mean “the following part runs in parallel”? Did you try to convert big PS file to PDF in multi-threading mode?

Hi @skolod
The issue happens, if multiple big PS files are converted in parallel in multiple threads

If so, please, provide us with full code that converts PS to PDF in several threads and PS test file that is converted.

I currently to not have a PS file that I can share with you.
If we convert the files sequential, we have no issue. If we convert the same PS files in parallel, we have the issue. We have testes it with the following code snipped:

        CompletableFuture<Void> f1 = CompletableFuture.runAsync(() -> {
            try {
                convert("9a3b4e094c5547efae68b63c4ead90e3638930430050619429.ps");
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });

        CompletableFuture<Void> f2 = CompletableFuture.runAsync(() -> {
            try {
                convert("81fd5efc149a4229831cd70c3e96e6e9638930430103165320.ps");
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });

        CompletableFuture<Void> f3 = CompletableFuture.runAsync(() -> {
            try {
                convert("c4a32597c5ed4ccb8c746acc5a46f264638930430155234324.ps");
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });

        CompletableFuture<Void> f4 = CompletableFuture.runAsync(() -> {
            try {
                convert("f01e3ba7a4824f5ba219b4916928ae95638930430175150728.ps");
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });

// Wait for all tasks to complete
        CompletableFuture.allOf(f1, f2, f3, f4).join();

@stud0r
convert() method is represented in your first code snippet, right?

yes, this is the first code snippet

@stud0r

And the last question. What is volume of big PS files that you will try to convert? Just to simulate the process the most closely to your case.

Hi @skolod
We have a test case with 4 parallel threads.
In the real world use case it’s more like two parallel threads, based on end user requests.

I meant how many Mbs PS files are in volume?

They are up to 300MB per ps file

@stud0r
We have opened the following new ticket(s) in our internal issue tracking system and will deliver their fixes according to the terms mentioned in Free Support Policies.

Issue ID(s): PAGEJAVA-344

You can obtain Paid Support Services if you need support on a priority basis, along with the direct access to our Paid Support management team.