The question pretty much says it all. I get following exception:
ExceptionConverter: java.io.IOException: /fonts/CALIBRI.TTF not found as file or resource.
Caused By: java.io.IOException: /fonts/CALIBRI.TTF not found as file or resource.
at com.itextpdf.text.io.RandomAccessSourceFactory.createByReadingToMemory(RandomAccessSourceFactory.java:263)
at com.itextpdf.text.io.RandomAccessSourceFactory.createBestSource(RandomAccessSourceFactory.java:173)
at com.itextpdf.text.pdf.RandomAccessFileOrArray.<init>(RandomAccessFileOrArray.java:148)
at com.itextpdf.text.pdf.TrueTypeFont.process(TrueTypeFont.java:641)
at com.itextpdf.text.pdf.TrueTypeFont.<init>(TrueTypeFont.java:375)
at com.itextpdf.text.pdf.BaseFont.getAllFontNames(BaseFont.java:1229)
at com.itextpdf.text.FontFactoryImp.register(FontFactoryImp.java:446)
at com.itextpdf.text.FontFactory.register(FontFactory.java:341)
at bean.createPdf.makePdf(createPdf.java:358)
at bean.auswahl.buttonProbenbegleitschein(auswahl.java:188)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.sun.el.parser.AstValue.invoke(AstValue.java:254)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:302)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:148)
at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
at org.apache.myfaces.trinidad.component.UIXComponentBase.broadcast(UIXComponentBase.java:1113)
at org.apache.myfaces.trinidad.component.UIXCommand.broadcast(UIXCommand.java:179)
at org.apache.myfaces.trinidad.component.UIXComponent.broadcastInContext(UIXComponent.java:364)
at oracle.adf.view.rich.event.ProxyEvent.broadcastWrappedEvent(ProxyEvent.java:72)
at oracle.adf.view.rich.component.fragment.UIXRegion.broadcast(UIXRegion.java:124)
at org.apache.myfaces.trinidad.component.UIXComponent.broadcastInContext(UIXComponent.java:364)
at org.apache.myfaces.trinidad.component.WrapperEvent.broadcastWrappedEvent(WrapperEvent.java:82)
at oracle.adf.view.rich.component.fragment.ContextSwitchingComponent$1.run(ContextSwitchingComponent.java:168)
at oracle.adf.view.rich.component.fragment.ContextSwitchingComponent._processPhase(ContextSwitchingComponent.java:510)
at oracle.adf.view.rich.component.fragment.ContextSwitchingComponent.broadcast(ContextSwitchingComponent.java:171)
at org.apache.myfaces.trinidad.component.UIXComponent.broadcastInContext(UIXComponent.java:364)
at org.apache.myfaces.trinidad.component.WrapperEvent.broadcastWrappedEvent(WrapperEvent.java:82)
at oracle.adf.view.rich.component.fragment.UIXInclude.broadcast(UIXInclude.java:111)
at org.apache.myfaces.trinidad.component.UIXComponent.broadcastInContext(UIXComponent.java:364)
at org.apache.myfaces.trinidad.component.WrapperEvent.broadcastWrappedEvent(WrapperEvent.java:82)
at oracle.adf.view.rich.component.fragment.ContextSwitchingComponent$1.run(ContextSwitchingComponent.java:168)
at oracle.adf.view.rich.component.fragment.ContextSwitchingComponent._processPhase(ContextSwitchingComponent.java:510)
at oracle.adf.view.rich.component.fragment.ContextSwitchingComponent.broadcast(ContextSwitchingComponent.java:171)
at oracle.adf.view.rich.component.fragment.UIXInclude.broadcast(UIXInclude.java:115)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._invokeApplication(LifecycleImpl.java:1074)
at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._executePhase(LifecycleImpl.java:402)
at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:225)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:346)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at oracle.adf.model.servlet.ADFBindingFilter.doFilter(ADFBindingFilter.java:192)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at oracle.adfinternal.view.faces.webapp.rich.RegistrationFilter.doFilter(RegistrationFilter.java:105)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:502)
at oracle.adfinternal.view.faces.activedata.AdsFilter.doFilter(AdsFilter.java:60)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:502)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._doFilterImpl(TrinidadFilterImpl.java:327)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl.doFilter(TrinidadFilterImpl.java:229)
at org.apache.myfaces.trinidad.webapp.TrinidadFilter.doFilter(TrinidadFilter.java:92)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at de.lkvsh.rdv.portal.authlib.servlet.PortalFilter.doFilter(PortalFilter.java:116)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at oracle.security.jps.ee.http.JpsAbsFilter$1.run(JpsAbsFilter.java:137)
at java.security.AccessController.doPrivileged(Native Method)
at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:315)
at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUtil.java:460)
at oracle.security.jps.ee.http.JpsAbsFilter.runJaasMode(JpsAbsFilter.java:120)
at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:217)
at oracle.security.jps.ee.http.JpsFilter.doFilter(JpsFilter.java:81)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at oracle.dms.servlet.DMSServletFilter.doFilter(DMSServletFilter.java:220)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3436)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3402)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2285)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2201)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2179)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1572)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:255)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:311)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)
Physical location of font file is /WEB-INF/resources/fonts/CALIBRI.TTF
So as far as I see it, it can't be not found in resources by iTextPDf FontFactory
.
Based on the source code of iText's RandomAccessSourceFactory#createBestSource()
, the FontFactory#register()
can only take a path representing a valid (relative) disk file system path, or a resource URL (e.g. HTTP URL or classpath URL), not a WAR resource path. You actually supplied a WAR resource path which you can usually pass to ServletContext#getResource()
, getResourceAsStream()
, getRealPath()
and getRequestDispatcher()
only.
There are several ways to get it to work:
Convert the WAR resource path to an absolute disk file system path with help of
ServletContext#getRealPath()
:String path = getServletContext().getRealPath("/WEB-INF/resources/fonts/foobar.ttf"); FontFactory.register(path);
The caveat is that this method is highly unportable and environment-dependent. Among others, this will fail when the server is configured to expand the WAR straight into memory instead of on local disk file system, or uses a virtual file system. E.g., by default, it may work on Tomcat, but it may not work on WebLogic. Your stack trace confirms that you're using WebLogic. The chance is big that the
getRealPath()
will by default always returnnull
.Move the font file outside
/WEB-INF
folder so that it's publicly accessible by a HTTP URL. Provided that you can move whole/resources
folder one level up, outside/WEB-INF
, and that the font is accessible byhttp://localhost:8080/context/resources/fonts/foobar.ttf
(first test in a normal webbrowser to be sure), then just supply exactly that path.String path = "http://localhost:8080/context/resources/fonts/foobar.ttf"; FontFactory.register(path);
You can if necessary dynamically construct
http://localhost:8080/context
(the base URL) as below:String url = request.getRequestURL().toString(); String baseURL = url.substring(0, url.length() - request.getRequestURI().length()) + request.getContextPath(); String path = baseURL + "/resources/fonts/foobar.ttf"; FontFactory.register(path);
The caveat is that, by default, anyone in the world could download it, even when only guessing the URL.
Move the font file to the classpath. I.e. make sure it ultimately ends up in
/WEB-INF/classes
among all those Java class files and class resource files (such as properties files). Let's assume that the package name is justfonts
. In case you're using Maven, just put it in/main/resources/fonts/foobar.ttf
. In case you're using a "plain vanilla" web project with only asrc
folder where you put all your Java packages and class source files, then create a packagefonts
the usual way and put thefoobar.ttf
file right there. Then you can supply a path of/fonts/foobar.ttf
.String path = "/fonts/foobar.ttf"; FontFactory.register(path);
This is clearly the preferred way.
In case none of above options apply, your last resort is creating a temporary file with help of
File#createTempFile()
in container managed temporary folder, grabbing the WAR resource contents byServletContext#getResourceAsStream()
, writing it to the temp file and finally provide the absolute temp file path.String tempDir = (String) getServletContext().getAttribute(ServletContext.TEMPDIR); File tempFile = File.createTempFile("foobar-", ".ttf", new File(tempDir)); InputStream input = getServletContext().getResourceAsStream("/WEB-INF/resources/fonts/foobar.ttf"); Files.copy(input, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING); String path = tempFile.getAbsolutePath(); FontFactory.register(path);
Note: the above answer assumes that the code is placed in a "plain" Java EE servlet class. In case you're using JSF — as confirmed by the stack trace — you can obtain the ServletContext
by ExternalContext#getContext()
, the HttpServletRequest
by ExternalContext#getRequest()
, the ServletContext
attributes by ExternalContext#getApplicationMap()
, the real path by ExternalContext#getRealPath()
, and the resource stream by ExternalContext#getResourceAsStream()
.
java.io.IOException: /fonts/CALIBRI.TTF not found as file or resource.
I think iText library is looking for fonts directly under WEB-INF folder instead of /WEB-INF/resources.
来源:https://stackoverflow.com/questions/32251711/load-font-from-web-inf-resources-fonts-foobar-ttf-with-itextpdf-fontfactory