Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4395902
Votes 3
Synopsis Font.createFont() causes SecurityException in JApplet
Category java:classes_2d
Reported Against 1.3 , merlin-beta
Release Fixed 1.4(merlin-beta2)
State 10-Fix Delivered, bug
Priority: 3-Medium
Related Bugs 4413118 , 4468862
Submit Date 07-DEC-2000
Description




java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

Font.createFont(int fontFormat, InputStream fontStream) causes a security
exception when called from within an applet.

Stack trace indicates that the implemention of createFont attempts to write the
retrieved font file to the local drive (SecurityException).  Seems that the font
needs to be cached in memory only.

//============================================
Example Code:

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.applet.*;
import javax.swing.JApplet;
import java.net.URL;
import java.io.*;

public class AppletWindow extends JApplet
{
    public void start()
    {
        try
        {
            URL fontURL = new URL("http://www.XXXXXX.com/Burmese.ttf");
            InputStream fontStream = fontURL.openStream();
            Font tempFont = Font.createFont(Font.TRUETYPE_FONT, fontStream);
            fontStream.close();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    public void stop(){}
    public void init(){}
    public void destroy(){}
}

//============================================
Plug-in Exception:

Java(TM) Plug-in: Version 1.3.0-C
Using JRE version 1.3.0 Java HotSpot(TM) Client VM
Proxy Configuration: no proxy

JAR cache disabled.
java.lang.SecurityException: Unable to create temporary file
	at java.io.File.checkAndCreate(File.java:1156)
	at java.io.File.createTempFile(File.java:1244)
	at java.awt.Font.createFont(Font.java:398)
	at AppletWindow.start(AppletWindow.java:19)
	at sun.applet.AppletPanel.run(AppletPanel.java:358)
	at java.lang.Thread.run(Thread.java:484)
(Review ID: 112326) 
======================================================================




C:\JBuilder4\jdk1.3\bin>.\java -version
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)


The following web page:

http://java.sun.com/j2se/1.3/docs/guide/2d/new_features.html#DF

Describes how to load dynamic fonts from a URL

Dynamic font loading
The new method Font.createFont(int, InputStream) provides the ability to add
fonts to the JavaTM 2 Virtual Machine* (JVM) at runtime. This font is not
 customer  upon termination of the JVM and is only available to the creator of
the Font. At this time, only TrueTypeTM fonts can be created at runtime.
The following code sample illustrates how to dynamically load the TrueType font
Arial from a file:


	File file = new File("Arial.ttf");
	FileInputStream fis = new FileInputStream(file);
	Font font = Font.createFont(Font.TRUETYPE_FONT, fis);
	
Similarly, to load the font from a URL:
	URL url = new URL("Arial.ttf");
	InputStream is = url.openStream();
	Font font = Font.createFont(Font.TRUETYPE_FONT, is);
	
When I use the sample for loading a font from a URL I get the following error:

java.lang.SecurityException: Unable to create temporary file
	at java.io.File.checkAndCreate(Unknown Source)
	at java.io.File.createTempFile(Unknown Source)
	at java.awt.Font.createFont(Unknown Source)
	at JinYoTimPiano.JinYoTimPiano.init(JinYoTimPiano.java:75)
	at sun.applet.AppletPanel.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)

Is it trying to create a temporary file on my system?
(Review ID: 114612)
======================================================================




java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

Put the applet and html file shown bellow and any True Type font to the web
server directory, run the applet using html file shown bellow (it uses
JavaPlugin 1.3), push the button "Download TTF file..." and enter URL to the
True Type font file in your webserver. After you push OK button, exception
message "java.lang.SecurityException: Unable to create temporary file" is shown
in text area.

Applet:

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.swing.*;

public class TTFRendererApplet extends JApplet implements ActionListener {
    private final String DEMO_TEXT = "The quick brown fox jumps over the lazy
dog. 1234567890";
    private final Font DEFAULT_FONT = new TextArea().getFont();
    
    private boolean bold = false;
    private boolean italic = false;
    
    private AbstractButton openButton;
    private AbstractButton boldButton;
    private AbstractButton italicButton;
    private AbstractButton sizeButton;
    private JTextField inputField;
    
    private JTextArea textArea;
    
    public TTFRendererApplet() {
        
        textArea = new JTextArea();
        textArea.setText(DEMO_TEXT);
        
        JScrollPane scrollPane = new JScrollPane(textArea);
        
        openButton = new JButton("Download TTF file...");
        openButton.addActionListener(this);

        boldButton = new JCheckBox("Bold");
        boldButton.addActionListener(this);

        italicButton = new JCheckBox("Italic");
        italicButton.addActionListener(this);
        
        inputField = new JTextField(6);
        
        sizeButton = new JButton("Change Size");
        sizeButton.addActionListener(this);

        JPanel buttonPanel = new JPanel();
        buttonPanel.add(openButton);
        buttonPanel.add(boldButton);
        buttonPanel.add(italicButton);
        buttonPanel.add(inputField);
        buttonPanel.add(sizeButton);

        Container contentPane = getContentPane();
        contentPane.add(scrollPane, BorderLayout.CENTER);
        contentPane.add(buttonPanel, BorderLayout.SOUTH);
    }
    
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == openButton) {
            textArea.setText("Loading font...");
            
            String urlStr = JOptionPane.showInputDialog(this, "Enter URL to TTF file:");
            URL url;
            try {
                url = new URL(urlStr);
            } catch (MalformedURLException ex) {
                textArea.setFont(DEFAULT_FONT);
                textArea.setText(ex.toString());
                return;
            }
                
            Font font = null;
            
            try {
                // This is where exception is thrown:

                font = Font.createFont(Font.TRUETYPE_FONT, url.openStream());
            } catch (FontFormatException ex) {
                textArea.setFont(DEFAULT_FONT);
                textArea.setText(ex.toString());
                return;
            } catch (IOException ex) {
                textArea.setFont(DEFAULT_FONT);
                textArea.setText(ex.toString());
                return;
            } catch (Exception ex) {
                textArea.setFont(DEFAULT_FONT);
                textArea.setText(ex.toString());
                return;
            }
            
            font = font.deriveFont(12.0f);
            
            textArea.setFont(font);
            
            textArea.setText(DEMO_TEXT);
        } else if (e.getSource() == boldButton || e.getSource() == italicButton) {
            if (e.getSource() == boldButton) {
                bold = !bold;
            } else if (e.getSource() == italicButton) {
                italic = !italic;
            }
        
            Font font = textArea.getFont();
            int style = Font.PLAIN;
            
            if (bold) {
                style |= Font.BOLD;
            }
            if (italic) {
                style |= Font.ITALIC;
            }
            
            font = font.deriveFont(style);
            textArea.setFont(font);
        } else if (e.getSource() == sizeButton) {
            String sizeStr = inputField.getText();
            float size = 12.0f;
            try {
                size = Float.valueOf(sizeStr).floatValue();
            } catch (NumberFormatException ex) {
                textArea.setFont(DEFAULT_FONT);
                textArea.setText(ex.toString());
                return;
            }
            
            Font font = textArea.getFont();
            font = font.deriveFont(size);
            textArea.setFont(font);
        }
    }

}


HTML file:

<html>
<head>
</head>
<body>

<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
    width="400" height="400"
    codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-
win32.cab#Version=1,3,0,0">
    <PARAM NAME="code" VALUE="TTFRendererApplet.class">
        No Java 2 SDK, Standard Edition v 1.3 support for APPLET!!
</OBJECT>

</body>
</html>
(Review ID: 106637)
======================================================================
Work Around




Have your browser grant the applet local disk writing access.
======================================================================
Evaluation
A temp file is created on the disk since the font can be very large.  We
should state in the javadoc that this might happen.
  xxxxx@xxxxx   2000-12-07

It was pointed out that we should also do a doPrivileged() to create this
temp file.
  xxxxx@xxxxx   2000-12-07

Fix: Added doPrivileged in all access to the temporary file.

  xxxxx@xxxxx   2001-05-31
===============================
Comments
  
  Include a link with my name & email   

Submitted On 12-DEC-2000
tbrunton
It seems that it would be better if browser didn't have to 
grant the applet local disk writing access just for using a 
font from the net.  In the case of Applets couldn't the 
font file just be written to the cache along with the 
*.class files and then cleaned up when the Applet is 
unloaded?


Submitted On 10-OCT-2001
cleanthes
alternatively, it would be nice if the temp file was 
optional, and at the discretion of the developer.  I have a 
font which is only 200k, so I really don't need any temp 
files to be written.



PLEASE NOTE: JDK6 is formerly known as Project Mustang