Solved

Copy and Paste in Applet

Posted on 2008-10-28
11
1,473 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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Unable to start eclipse ? 17 128
maven example error 3 52
eclipse argument 14 53
windows explorer path to command prompt 5 27
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

929 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

9 Experts available now in Live!

Get 1:1 Help Now