Solved

Copy and Paste in Applet

Posted on 2008-10-28
11
1,469 Views
Last Modified: 2013-12-14
I am trying to create a simple text editor in Java for my website. When attempt to paste content from the clipboard (using the source shown below) I am getting the following exception:

java.security.AccessControlException: access denied
(java.awt.AWTPermission accessClipboard)

From a Google search I have been led to believe that it is possible to sign the applet so that it gains the required permission. Or perhaps there is another way I can do this?

If it's of any difference, I use JCreator for creating Java applets.
Clipboard clipboard = getToolkit().getSystemClipboard();

Transferable clipboardContent = clipboard.getContents(this);

if (clipboardContent != null && clipboardContent.isDataFlavorSupported (DataFlavor.stringFlavor))

{

	try

	{

		result = (String)clipboardContent.getTransferData(DataFlavor.stringFlavor);

	}

	catch(Exception e)

	{

	}

}

Open in new window

0
Comment
Question by:numberkruncher
  • 6
  • 5
11 Comments
 
LVL 8

Expert Comment

by:n_sachin1
ID: 22828930
The java applets run in a sandbox provided by the jre and cannot by default access any properties from the client system. The clipboard is also a client system resource and you would need to sign the applet to access it.
Signing your applet would be the only clean solution. You sure can do a self-signing.

The only other way I can think of is via javascript-Applet communication. Have the text area as a html input (instead of a java control). On ctrl+v, trigger a call to your applet. This would however be pretty workaroundish.
0
 
LVL 13

Author Comment

by:numberkruncher
ID: 22829478
Could you please explain how I go about signing the applet?

When I build the applet in JCreator it gives me a selection of class files. The class file is then associated with the HTML page. What is the difference between a JAR and a class file? Is a JAR just an archive of class files?
0
 
LVL 8

Expert Comment

by:n_sachin1
ID: 22829744
yes. A jar is just a archive of class files with a few specific additions. It contains a META-INF folder with a manifest.mf file (contains information about the jar and special clauses like a main class, classpaths etc. - not specifically relevant for your applet).

When you are using a jar, In the html applet tag, you would need to specify an 'archive' attribute that will be the location of the jar file and you can get rid of codebase (that you might be specifying to show the base location of your class).

I'd suggest you read this:
http://java.sun.com/docs/books/tutorial/deployment/jar/signing.html
The link will give you a general overview of jars, and a brief on signing.

A signed applet basically means - packaging the class files in a jar and then, signing the jar with your key/digital certificate, so that when users of your applet download it, they know that its from you, and they can trust it.

Read the first post at this link about the entire signing process in brief:
http://forums.sun.com/thread.jspa?threadID=174214
0
 
LVL 13

Author Comment

by:numberkruncher
ID: 22833541
Thanks for the links!

I've read through and tried to follow the instructions to generate and sign a jar. It says that the certificate should be valid for 6 months. In web browsers the following causes a "htmlEditor.class" not found error, but within JCreator it appears to open the .jar file with the same HTML (#1).

I also tried using the HtmlConverter utility, but still no luck.

I have also tried using (#2), but this also causes the clipboard security exception.
#1:
 

<applet

	 id		= "myApplet"

	 archive	= "htmlEditor.jar"

	 width	= "500"

	 height	= "300"

	 code	= "htmlEditor"

	>

</applet>
 
 

#2:

	public String doSomething() {

		String result = "";

			

	    result = (String)java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() {

			public Object run() {

				String result = "";

				

				Clipboard clipboard = getToolkit().getSystemClipboard();

				Transferable clipboardContent = clipboard.getContents(this);

				if (clipboardContent != null && clipboardContent.isDataFlavorSupported(DataFlavor.stringFlavor))

				{

					try

					{

						result = (String)clipboardContent.getTransferData(DataFlavor.stringFlavor);

					}

					catch(Exception e)

					{

					}

				}

				return result;

			}

	    });

		

		return result;

	}

Open in new window

0
 
LVL 8

Expert Comment

by:n_sachin1
ID: 22838192
Try this on your html applet tag:
<applet
       name            = "myApplet"
       archive      = "htmlEditor.jar"
       width      = "500"
       height      = "300"
       code      = "<fully qualified class name like com.test.htmlEditor.class if thats the name>"
      >
</applet>

You need to ensure that the htmlEditor.jar is in the same location (for eg:- for the above archive def, place the jar and the html in the same folder.

Do you use ANT? If yes, attach your html and the applet code and I'll give you a sample ant build script to jar and sign it.

0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 13

Author Comment

by:numberkruncher
ID: 22844018
I have not used ANT before, but JCreator does offer the ability to create ANT files, so that would be brilliant. I have added my HTML and Applet code below.

I have simplified the applet to the bare minimum which causes the clipboard security access error.
HTML:

=====

<html>

	<head>

		<title>Test Page</title>

		<script type="text/javascript">

			function test() {

				var myApplet = document.getElementById('myApplet');

				if (myApplet)

					alert(myApplet.doSomething());

				else

					alert('Invalid applet!');	

			}

		</script>

	</head>

	<body>

		<center style="border: solid 1px black">

			<applet

				id		= "myApplet"

				class	= "htmlEditor.class"

				width	= "500"

				height	= "300"

				code	= "htmlEditor"

				>

			</applet>

		</center>

		<br />

		<input type="button" value="Do Something!" onclick="test()" />

	</body>

</html>
 
 

Java Applet:

============

import java.applet.*;

import java.io.*;

import javax.swing.event.*;

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

import javax.swing.text.html.*;

import javax.swing.text.*;

import java.net.*;

import java.awt.datatransfer.*;
 

public class htmlEditor extends JApplet {

	public htmlEditor() {

	}
 

	public void init() {

	}
 

	public String doSomething() {

		String result = "";

			

	    result = (String)java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() {

			public Object run() {

				String result = "";

				

				Clipboard clipboard = getToolkit().getSystemClipboard();

				Transferable clipboardContent = clipboard.getContents(this);

				if (clipboardContent != null && clipboardContent.isDataFlavorSupported(DataFlavor.stringFlavor))

				{

					try

					{

						result = (String)clipboardContent.getTransferData(DataFlavor.stringFlavor);

					}

					catch(Exception e)

					{

					}

				}

				return result;

			}

	    });

		

		return result;

	}

}

Open in new window

0
 
LVL 8

Expert Comment

by:n_sachin1
ID: 22847929
Now I see your issue, and why the previous comment didn't work for you.
You are trying to invoke an applet method from javascript (more like - 'the workaroundish way' I talked about.
Well, modern jres do not treat java script as a secure app. Thus, if a applet method called by a javascript tries to do privileged operations, it denies it (even if the applet is signed).

You would need to have a Thread that listens for your java script call..and then, delegates the request to another thread (created outside the context of this method called by javascript - may be in init() ),
0
 
LVL 8

Accepted Solution

by:
n_sachin1 earned 500 total points
ID: 22847969
Ok, I have corrected a few things:
1. Your applet needs to reside in a package.
2. Please see my previous comment about accessing applet methods from javascript and its security implications.
//The applet changes for signing to work.

package numberkruncher;

....

public class htmlEditor extends JApplet {

.....

}
 

//The html file

<html>

	<head>

		<title>Test Page</title>

		<script type="text/javascript">

			function test() {

				var myApplet = document.getElementById('myApplet');

				if (myApplet)

					alert(myApplet.doSomething());

				else

					alert('Invalid applet!');	

			}

		</script>

	</head>

	<body>

		<center style="border: solid 1px black">

			<applet

				id		= "myApplet"

				code	= "numberkruncher.htmlEditor.class"

				width	= "500"

				height	= "300"

				archive	= "numberkruncher.jar"

				>

			</applet>

		</center>

		<br />

		<input type="button" value="Do Something!" onclick="test()" />

	</body>

</html>
 

//The ant script that does the jar and signs the applet

//You need to follow the following folder structure or adapt the script

//<root>--src (source files and html)

//      --bin (compiled classes will go here)    

//      --dist (will contain the signed jar and the html)  

//      --KeyStore (will contain your Key Store)

<?xml version="1.0" encoding="UTF-8"?>
 

<project basedir="." default="all" name="numberkruncher">

	

	<property file="${basedir}/build.properties"/>

	<property name="bin" value="${basedir}/bin" />

	<property name="src" value="${basedir}/src" />

	<property name="dist" value="${basedir}/dist" />

	<property name="app.jar" value="numberkruncher.jar" />

	

	<path id="project.class.path">

		<pathelement location="${bin}" />

	</path>

	

	<target name="clean">

		<delete file="${dist}/${app.jar}" />

		<delete failonerror="false" includeemptydirs="true">

			<fileset dir="${bin}" />

		</delete>

	</target>

	

	<target name="init">

		<mkdir dir="${bin}" />

		<mkdir dir="${dist}" />

	</target>
 

	<target  name="compile" depends="init">

		<javac classpathref="project.class.path" destdir="${bin}">

			<src path="${src}" />

		</javac>

	</target>

	

	<target name="dist"  depends=" compile">

		<jar compress="true" destfile="${dist}/${app.jar}">

			<fileset dir="${bin}">

				<include name="**/*.class" />

			</fileset>

			<manifest>

				<attribute name="Main-Class" value="htmlEditor" />

			</manifest>

		</jar>

		<copy todir="${dist}">

			<fileset dir="${src}">

				<include name="**/*.html" />

			</fileset>

		</copy>

	</target>

	

	<target name="keytoolexec" unless="keystore.exists">

		<mkdir dir="${basedir}/Keystore"/>

		<exec dir="${basedir}" executable="keytool" failonerror="true">

			<arg value="-genkey "/>

			<arg value="-alias" />

			<arg value="numberkruncher"/>

			<arg value="-keystore" />

			<arg value="${basedir}/Keystore/Kruncher.jks"/>	

			<arg value="-keypass" />

			<arg value="n_sachin1"/>

			<arg value="-dname" />

			<arg value="CN=Test CA, OU=NK, O=NK, L=Bangalore, S=KA, C=IN"/>	

			<arg value="-storepass" />

			<arg value="n_sachin1"/>

			<arg value="-validity" />

			<arg value="365"/>

			

		</exec> 

	</target>

	

	<target name="testKeyStore">

		<available property="keystore.exists" file="${basedir}/Keystore/Kruncher.jks" />

	</target>
 

	  <target name="signjar" depends="dist, testKeyStore, keytoolexec">

	  	

	    <echo message="------ Signing JAR files"/>

	     <signjar jar="${dist}/${app.jar}" storepass="n_sachin1" alias="numberkruncher"

	           keystore="${basedir}/Keystore/Kruncher.jks" keypass="n_sachin1" />

	  </target>
 

	

	<target name="all" depends="clean, dist, signjar"/>

</project>

Open in new window

0
 
LVL 8

Expert Comment

by:n_sachin1
ID: 22847983
Below is the modified applet code (full).
As you can see, you can simply do a ctrl+v to paste string contents in your text area, or have the 'Do Something' button inside your applet, to eliminate the need for a java script to applet call.

Let me know if it was helpful.
package numberkruncher;
 

import java.awt.datatransfer.Clipboard;

import java.awt.datatransfer.DataFlavor;

import java.awt.datatransfer.Transferable;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.KeyEvent;
 

import javax.swing.JApplet;

import javax.swing.JComponent;

import javax.swing.JTextArea;

import javax.swing.KeyStroke;
 

public class htmlEditor extends JApplet {
 

	private JTextArea jTxtArea = null;
 

	public htmlEditor() {

	}
 

	public void init() {

		if (jTxtArea == null) {

			jTxtArea = new JTextArea();
 

			KeyStroke paste = KeyStroke.getKeyStroke(KeyEvent.VK_V,

					ActionEvent.CTRL_MASK, false);

			ActionListener al = new ActionListener() {
 

				public void actionPerformed(ActionEvent arg0) {

					jTxtArea.setText(doSomething());

				}
 

			};
 

			jTxtArea.registerKeyboardAction(al, "Paste", paste,

					JComponent.WHEN_FOCUSED);
 

			this.add(jTxtArea);

		}

	}
 

	public String doSomething() {

		String result = "";
 

		result = (String) java.security.AccessController

				.doPrivileged(new java.security.PrivilegedAction() {

					public Object run() {

						String result = "";
 

						Clipboard clipboard = getToolkit().getSystemClipboard();

						Transferable clipboardContent = clipboard

								.getContents(this);

						if (clipboardContent != null

								&& clipboardContent

										.isDataFlavorSupported(DataFlavor.stringFlavor)) {

							try {

								result = (String) clipboardContent

										.getTransferData(DataFlavor.stringFlavor);

							} catch (Exception e) {

								StackTraceElement[] stacks = e.getStackTrace();

								StringBuffer sBuff = new StringBuffer("");

								for (int i = 0; i < stacks.length; i++) {

									sBuff.append(stacks[i].toString()).append(

											"\n");

								}
 

								result = sBuff.toString();

							}

						}

						return result;

					}

				});
 

		return result;

	}

}

Open in new window

0
 
LVL 13

Author Comment

by:numberkruncher
ID: 22849790
That works perfectly!
0
 
LVL 13

Author Closing Comment

by:numberkruncher
ID: 31510969
Thanks again for all of your time and effort, it is much appreciated!
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Here is a helpful source code for C++ Builder programmers that allows you to manage and manipulate HTML content from C++ code, while also handling HTML events like onclick, onmouseover, ... Some objects defined and used in this source include: …
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now