I have created simple Java class to test file writes from applets:
update appeared
public class localfile extends Applet{
public localfile(){
try {
File f = new File("testfile.txt");
BufferedWriter out = new BufferedWriter(new FileWriter(f,true));
out.write("test");
out.close();
}
catch(Exception x)
System.err.println(x.toString());
}
}
I have created and signed jar:
jar cvf localfile.jar localfile.java
jarsigner localfile.jar yourkey
html looks like:
<applet code="localfile.class" archive="localfile.jar", width=300, height=600>
The error I get every time I run this applet is:
java.lang.SecurityException: trusted loader attempted to load sandboxed resource from file:/home/w/test/
at com.sun.deploy.security.CPCallbackHandler$ParentCallback.check(CPCallbackHandler.java:308)
at com.sun.deploy.security.CPCallbackHandler$ParentCallback.access$1400(CPCallbackHandler.java:121)
at com.sun.deploy.security.CPCallbackHandler$ChildElement.checkResource(CPCallbackHandler.java:473)
at sun.plugin2.applet.Plugin2ClassLoader.checkResource(Plugin2ClassLoader.java:701)
at sun.plugin2.applet.Applet2ClassLoader.findClass(Applet2ClassLoader.java:206)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at sun.plugin2.applet.Plugin2ClassLoader.loadCode(Plugin2ClassLoader.java:520)
at sun.plugin2.applet.Plugin2Manager.createApplet(Plugin2Manager.java:2940)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Plugin2Manager.java:1444)
at java.lang.Thread.run(Thread.java:619)
Exception: java.lang.SecurityException: trusted loader attempted to load sandboxed resource from file:/home/w/test/
What is strange: I have created similar applet to read files and it works ok.
Any thoughts?
I was running this applet on both browser and applet viewer. What is strange given applet doesn't work on applet viewer and throws exception, but on browser it is fine.
java.security.AccessControlException: access denied (java.util.PropertyPermission java.security.policy write)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323)
at java.security.AccessController.checkPermission(AccessController.java:546)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
at java.lang.System.setProperty(System.java:725)
at localfile.<init>(localfile.java:15)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at java.lang.Class.newInstance0(Class.java:355)
at java.lang.Class.newInstance(Class.java:308)
at sun.applet.AppletPanel.createApplet(AppletPanel.java:785)
at sun.applet.AppletPanel.runLoader(AppletPanel.java:714)
at sun.applet.AppletPanel.run(AppletPanel.java:368)
at java.lang.Thread.run(Thread.java:619)
So, beside this strange behaviour I consider my problem solved. Thanks everyone:)
Did you provide a policy to allow reading files from the filesystem?
Seems that you only signed the jar but didn't use policytool.
With some finagling, you can include a policy file in a jar. Refer to the SO question jar policy file for more information.
Otherwise, consider making a Java WebStart application, which can read/write files more easily.
http://java.sun.com/docs/books/tutorial/security/tour1/step2.html
This should help you out with creating the policy file and associating with your code base
I knew this is quite late. But just to help whoever look-up to this error -
Using Ant, multiple jars can be signed at one shot, for example java-comm.jar etc
<target name="applet.sign" description="Sign the applet jar">
<signjar jar="${applet.dir}/*.jar"
storepass="${applet.key.password}"
keystore="${applet.keystore}"
alias="${applet.key.alias}"
keypass="${applet.key.password}" />
This wil sign all the jar in the directory.
I believe your problem is that directory including the file you are trying to load is within the codebase where class files and application resources are looked up. So, you end up mixing trusted and untrusted resources, which is not secure. If the applet is hosted on an http, or better https, server then the issue doesn't arise for files.
Note you can use the JNLP APIs for applets to "open" or write files through a file dialog.
Your resource handling leaves the file open in the case of exceptions. Resource handling should be written in the style:
Resource resource = acquire();
try {
use(resource);
} finally {
resource.release();
}
In your specific case:
final FileOutputStream rawOut = new FileOutputStream(file);
try {
...
out.flush();
} finally {
rawOut.close();
}
Related
I have a self signed applet running in the browser, this applet should create a directory on the client machine using this code.
boolean success = (new File("myDir")).mkdirs();
if (!success) {
System.err.println("Directory creation failed");
}
However, when I run it in the browser (under Apache) and after accepting all the security warnings I can't find myDir directory on my machine.
Am I doing something wrong?
I guess you are not looking at the right place...
Given your code snippet, this directory will be created in the current working directory. To be sure where that is on your machine just try to see what the following code gives out :
System.out.println(System.getProperty("user.dir"));
You're not giving it an absolute path so it's creating myDir in the working directory that the browser runs it in, probably a temp dir, or even a "sandbox" area in some browsers.
Because you run applet in sandbox, so You cannot access into user machine resource.
Please see document:
Applet security
I have a Java project that contains 1 JApplet.
I'm able to run the Applet in desk-top mode (adding the applet to a frame in main[] method).
It doesn't work in a browser though. Getting this error:
I already signed all the jars.
I believe its related to mysql connector jar.
Any ideas?
Exception occurred: java.lang.ExceptionInInitializerError (uncaught)"thread=AWT-
EventQueue-1", java.awt.EventDispatchThread.run(), line=156 bci=152
It runs fine if I add grant all to java.policy
You should ensure:
That your applet is signed to allow for database connections.
That your mysql connector jar is available on your 'download' path just like your applet jar file.
Running the application from a webserver solved the issue.
Before I begin I would like to mention that I have researched this thoroughly and have yet to find a solution which has worked for me (a good 2-3 days of research).
Currently using :
WAMPServer Version 2.1 (Apache service disabled)
Eclipse-jee x64
javac 1.6.0_22
Windows 7 x64
The applet, webpage, and database are all residing on my local computer.
First and foremost my applet works without issues in the Eclipse IDE, however I am constantly recieving the following error when attempting to run it as applet.html with the following script:
<applet code="GUI.class"
name="Some name goes here"
archive="APTracker.jar"
width="1000" height="700">
Your browser is not Java enabled.
</applet>
I have exported my class files using Eclipse IDE which has included the manifest into appletJar.jar.
The Jar exported by Eclipse does NOT contain the mysql-connector library
After assembling my class files I manually extracted the com and org files from the mysql-connector jar and
input them into my appletJar.jar
Following this I signed my applet jar (and confirmed it is signed) with a key which expires in 6 months.
After these steps I still receive the error message shown below.
I have tried replacing localhost with 127.0.0.1 which did not work. I have also tried placing the mysql-connector.jar
in the jre, jdk, and root class files which showed no change.
private final String DRIVER = "com.mysql.jdbc.Driver";
private final String DATABASE_URL = "jdbc:mysql://localhost:3306/javadb";
private final String USERNAME = "xxxxxx";
private final String PASSWORD = "xxxxxx";
private Connection connection = null;
private PreparedStatement selectAllAirports = null;
private ResultSet resultSet;
private ResultSetMetaData metaData;
/* Establish PreparedStatements */
public ResultSetTableModel()
{
try
{
//establish connection to database
connection = DriverManager.getConnection(DATABASE_URL, USERNAME, PASSWORD);
//load driver class
Class.forName( DRIVER );
//create prepared statements
selectAllAirports = connection.prepareStatement( "SELECT asciiname, latitude, longitude, elevation, timezone, country_code FROM geoname;" );
}
catch ( SQLException sqlException )
{
sqlException.printStackTrace();
//System.exit(1);
}
catch ( ClassNotFoundException classNotFound )
{
System.out.println("ClassNotFoundException triggered.");
classNotFound.printStackTrace();
}
}
This is the error message which I receive:
C:\Users\Mr.\Desktop\Applet>appletviewer applet.html
java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/javadb
at java.sql.DriverManager.getConnection(DriverManager.java:602)
at java.sql.DriverManager.getConnection(DriverManager.java:185)
at ResultSetTableModel.(ResultSetTableModel.java:38)
at GUI.(GUI.java:20)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at java.lang.Class.newInstance0(Class.java:355)
at java.lang.Class.newInstance(Class.java:308)
at sun.applet.AppletPanel.createApplet(AppletPanel.java:785)
at sun.applet.AppletPanel.runLoader(AppletPanel.java:714)
at sun.applet.AppletPanel.run(AppletPanel.java:368)
at java.lang.Thread.run(Thread.java:662)
java.lang.ArrayIndexOutOfBoundsException: 0 >= 0
at java.util.Vector.elementAt(Vector.java:427)
at javax.swing.table.DefaultTableColumnModel.getColumn(DefaultTableColumnModel.java:277)
at GUI.init(GUI.java:60)
at sun.applet.AppletPanel.run(AppletPanel.java:424)
at java.lang.Thread.run(Thread.java:662)
Note that recent JDBC drivers don't need the Class.forName() call if the service loader method is supported.
The current Connector/J version does support that, but by including only the org and com directories of the JDBC driver you "broke" it: The service loader mechanism depends on files under the META-INF directory.
So with your setup you would indeed need the Class.forName() call. But in your code that code is after the attempt to get the connection, which won't do any good.
So do one of those:
Add the relevant service files from the JDBC driver (under META-INF/services) to your jar file (and get rid of the unnecessary Class.forName() call) or
Put the Class.forName() call before the DriverManager.getConnection() call.
Rather than trying to manually put the MySQL class files into your APTracker.jar, why not just include the MySQL jar on the applet's classpath?
I suspect there is something in the MySQL jar file's META-INF directory that you need - a ServiceLoader configuration file or some such.
Things to consider are:
Do you have mysql-connector-java-5.1.10.jar or any related connector in your machine? If none, ask it in google?
If you have, paste the connector at C:\Program Files\Java\jdk...\jre\lib\ext directory.
Edit the applet tag on archive as archive = APTracker.jar, mysql-connector-java-5.1.10.jar
Paste again the mysql-connector-java-5.1.10.jar to where the files like .html, .class and the like are located.
I guess the MySQL JDBC jar is missing.
you can download that jar from: http://www.mysql.com/downloads/connector/j/
I worked on a JSP code that is runnning on a Tomcat5.5 server in windows system .
I had to copy all the JSP code to a linux system and when I did the same I got an error stating below.
javax.servlet.ServletException: c:\tmp is not a directory
Readcsv.init(Readcsv.java:36)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:875)
org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
java.lang.Thread.run(Thread.java:636)
I modified a java code in the windows system without that c:\tmp directory and restarted the tomcat server and the tool worked fine.
When I replaced the modified java code of windows to the linux system, I still get the same error.
Note: Am accessing the linux server from windows using the url http://192.168.0.85:8080/CNA/uploadcsv.jspwhere 85 is the system number of linux.
Is there anything like tomcat has to be restarted for the linux version too? If so how to do the same?
UPDATE
This is where I have used the c:\tmp location in my code.
public class Readcsv extends HttpServlet {
private static final String TMP_DIR_PATH = "c:\tmp";
private File tmpDir;
private static final String DESTINATION_DIR_PATH ="/files";
private File destinationDir;
public void init(ServletConfig config) throws ServletException {
super.init(config);
tmpDir = new File(TMP_DIR_PATH);
if(!tmpDir.isDirectory()) {
throw new ServletException(TMP_DIR_PATH + " is not a directory");
}
String realPath = getServletContext().getRealPath(DESTINATION_DIR_PATH);
destinationDir = new File(realPath);
if(!destinationDir.isDirectory()) {
throw new ServletException(DESTINATION_DIR_PATH+" is not a directory");
}
}
How can I find the replacement for the temp path? The destination path works fine.
I exactly copied the code from this example
Don't hardcode disk file system paths in your code. That's only portability and maintainability trouble.
In case of temporary files, rather make use of File#createTempFile().
File tempfile = File.createTempFile("name", ".ext");
It will automatically create the temp file at the right location, regardless of the environment. You can however also obtain the tmp dir root location by System.getProperty("java.io.tmpdir");.
In case of resources which are to be read by your application, just put them in the runtime classpath or add their path to the runtime classpath. Then you can just obtain them from the classpath by getResource() and getResourceAsStream() methods on Class or ClassLoader.
InputStream input = getClass().getResourceAsStream("file.properties");
If you really need to have a fixed path outside the classpath, then rather define it in a properties file so that you at least have any control over the path from outside the application (so, without the need to change the code everytime).
String path = properties.getProperty("my.file.path");
it seems that your application try to read a csv file under "C:\tmp" which doesn't exist on your linux system.
You said you modified the code and redeployed it to Tomcat.
You probably just need to restart Tomcat to get it to pick up the new code. Until then, it will be running the old code and you will get the same error.
How you restart Tomcat depends on which Linux distribution you are running and how you installed Tomcat.
i am getting a problem
i have deployed a war file, when i run localy through tomcat it works fine but when i run on another system by giveing my system ip and then project folder e.g
http:\192.168.0.145\DllTest it loads the applet but when i click on a button to load the functionality it is throwing an exception
Exception in thread "AWT-EventQueue-3" java.lang.UnsatisfiedLinkError: Expecting an absolute path of the library: http:\192.168.0.145:8080\DllTest\lib\jinvoke.dll
while it is working fine localy but not in another system. Please tell me what is the problem.
Is it a rights issue or something else.
You cannot load a DLL on an external host. It has to be an absolute disk file system -as the exception message already hints. Your best bet is to download it manually, create a temp file and load it instead.
File dllFile = File.createTempFile("jinvoke", ".dll");
InputStream input = new URL(getCodeBase(), "lib/jinvoke.dll").openStream();
OuptutStream output = new FileOutputStream(dllFile);
// Write input to output and close streams the usual Java IO way.
// Then load it using absolute disk file system path.
System.loadLibrary(dllFile.getAbsolutePath());
dllFile.deleteOnExit();