Laravel 9共享主机上mikehaertl/php-pdftk无法正常工作求助
Laravel 9使用php-pdftk填充PDF表单部署共享主机报错问题
开发Laravel 9项目时,使用mikehaertl/php-pdftk工具从数据库填充PDF表单,部署到共享主机后出现错误:提示找不到Java证书文件/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre/lib/security/cacerts,无法打开指定PDF文件。但相同主机和域名下的原生PHP代码可正常运行,Laravel代码报错,相关代码及错误信息如下:
错误信息
Error: Unexpected Exception in open_reader() java.lang.RuntimeException: java.lang.RuntimeException: error instantiating default socket factory: java.security.KeyManagementException: java.security.KeyStoreException: java.io.FileNotFoundException: /usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre/lib/security/cacerts (No such file or directory) at javax.net.ssl.SSLSocketFactory$ErrorSocketFactory.createSocket(libgcj.so.10) at gnu.java.net.protocol.http.HTTPConnection.getSocket(libgcj.so.10) at gnu.java.net.protocol.http.HTTPConnection.getOutputStream(libgcj.so.10) at gnu.java.net.protocol.http.Request.dispatch(libgcj.so.10) at gnu.java.net.protocol.http.HTTPURLConnection.connect(libgcj.so.10) at gnu.java.net.protocol.http.HTTPURLConnection.getInputStream(libgcj.so.10) at java.net.URL.openStream(libgcj.so.10) at pdftk.com.lowagie.text.pdf.RandomAccessFileOrArray.(pdftk) at pdftk.com.lowagie.text.pdf.RandomAccessFileOrArray.(pdftk) at pdftk.com.lowagie.text.pdf.PRTokeniser.(pdftk) at pdftk.com.lowagie.text.pdf.PdfReader.(pdftk) at pdftk.com.lowagie.text.pdf.PdfReader.(pdftk) Caused by: java.lang.RuntimeException: error instantiating default socket factory: java.security.KeyManagementException: java.security.KeyStoreException: java.io.FileNotFoundException: /usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre/lib/security/cacerts (No such file or directory) at javax.net.ssl.SSLSocketFactory.getDefault(libgcj.so.10) at javax.net.ssl.HttpsURLConnection.getDefaultSSLSocketFactory(libgcj.so.10) at javax.net.ssl.HttpsURLConnection.getSSLSocketFactory(libgcj.so.10) ...8 more Caused by: java.security.KeyManagementException: java.security.KeyStoreException: java.io.FileNotFoundException: /usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre/lib/security/cacerts (No such file or directory) at gnu.javax.net.ssl.provider.SSLContextImpl.defaultTrustManager(libgcj.so.10) at gnu.javax.net.ssl.provider.SSLContextImpl.engineInit(libgcj.so.10) at javax.net.ssl.SSLContext.init(libgcj.so.10) at javax.net.ssl.SSLSocketFactory.getDefault(libgcj.so.10) ...10 more Caused by: java.security.KeyStoreException: java.io.FileNotFoundException: /usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre/lib/security/cacerts (No such file or directory) at gnu.javax.net.ssl.provider.X509TrustManagerFactory.engineInit(libgcj.so.10) at javax.net.ssl.TrustManagerFactory.init(libgcj.so.10) at gnu.javax.net.ssl.provider.SSLContextImpl.defaultTrustManager(libgcj.so.10) ...13 more Caused by: java.io.FileNotFoundException: /usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre/lib/security/cacerts (No such file or directory) at gnu.java.nio.channels.FileChannelImpl.open(libgcj.so.10) at gnu.java.nio.channels.FileChannelImpl.(libgcj.so.10) at gnu.java.nio.channels.FileChannelImpl.create(libgcj.so.10) at java.io.FileInputStream.(libgcj.so.10) at java.io.FileInputStream.(libgcj.so.10) at gnu.javax.net.ssl.provider.X509TrustManagerFactory.engineInit(libgcj.so.10) ...15 more Error: Failed to open PDF file: https://tax-ein-number.com/pdf/fss4.pdf Errors encountered. No output created. Done. Input errors, so no output created.
Laravel控制器代码
use mikehaertl\pdftk\Pdf; class FillAblePdfController extends Controller { public function autofillpdf_ss4(Request $request, $order_id) { $filename = 'pdf_'.rand(2000, 1200000).'.pdf'; $pdf = new Pdf(asset('/pdf/fss4.pdf'),[ 'command' => public_path('/pdftk/bin/pdftk'), 'procEnv' => ['LD_LIBRARY_PATH' => public_path('pdftk/bin/libgcj.so.10')] ]); $result = $pdf->fillForm([ 'topmostSubform[0].Page1[0].f1_40[0]' => 'Jhon', ])->needAppearances()->saveAs(asset('pdf/'.$filename)); if ($result === false) { echo $pdf->getError(); } } }
可正常运行的原生PHP代码
require_once 'vendor/autoload.php'; use mikehaertl\pdftk\Pdf; $filename = 'pdf_'.rand(2000, 1200000).'.pdf'; $pdf = new Pdf('./fss4.pdf',['command' => './pdftk/bin/pdftk','procEnv' => ['LD_LIBRARY_PATH' => './pdftk/lib/libgcj.so.10']]); $result = $pdf->fillForm([ 'topmostSubform[0].Page1[0].f1_40[0]' => 'Ali' ])->needAppearances() ->saveAs('./pdf/'.$filename); if ($result === false) { echo $pdf->getError(); } echo 'Your PDF is now generated, <a href="./pdf/'.$filename.'" download>Download it here</a>';
问题解决办法
核心问题分析
- Laravel代码使用
asset()生成HTTPS URL加载PDF,触发pdftk通过网络请求读取文件,进而触发Java证书查找逻辑;而原生PHP直接使用本地文件路径,规避了该问题。 LD_LIBRARY_PATH配置错误:该变量应指向包含libgcj.so.10的目录,而非文件本身。saveAs()使用asset()生成的URL作为保存路径,属于错误用法,需用本地绝对路径。
修改后的Laravel控制器代码
use mikehaertl\pdftk\Pdf; use Illuminate\Http\Request; class FillAblePdfController extends Controller { public function autofillpdf_ss4(Request $request, $order_id) { $filename = 'pdf_'.rand(2000, 1200000).'.pdf'; // 使用本地绝对路径加载PDF,避免HTTPS请求触发证书问题 $pdfSourcePath = public_path('/pdf/fss4.pdf'); $pdf = new Pdf($pdfSourcePath, [ 'command' => public_path('/pdftk/bin/pdftk'), // 配置LD_LIBRARY_PATH指向libgcj.so.10所在目录 'procEnv' => ['LD_LIBRARY_PATH' => public_path('pdftk/lib')] ]); $savePath = public_path('pdf/'.$filename); $result = $pdf->fillForm([ 'topmostSubform[0].Page1[0].f1_40[0]' => 'Jhon', ])->needAppearances()->saveAs($savePath); if ($result === false) { echo $pdf->getError(); } } }
额外排查点
- 确认共享主机上
public/pdftk/lib/libgcj.so.10文件存在且权限为可读。 - 若仍有Java环境相关问题,可尝试在
procEnv中添加JAVA_HOME指向主机上可用的JRE路径(如'JAVA_HOME' => '/usr/lib/jvm/java-1.8.0-openjdk',需根据主机实际情况调整)。
内容的提问来源于stack exchange,提问作者MShoaib
相关产品推荐
相关产品推荐

