Calling a DLL from an Applet via JNI - java

I have a "proof of concept" piece of work that crosses over into some unfamiliar territory.
I'm tasked with connecting an EFTPOS machine to an application running as an applet in a browser on our intranet.
I've ignored the EFTPOS dll for the moment and created a simple JNI decorated DLL in my language of choice (Delphi) that just logs a string to a text file in c:\ and I can call it successfully from a local Java application.
However, when I create an applet to do the same thing, compile it into a .JAR, sign the JAR & try to call the method in the applet via Javascript on a web page it fails.
A senior Java guy I'm working with doesn't think it will be possible to get this to work because it's inherently "evil" to allow an applet to do this.
There is an entry you can put in a java.policy file to allow loadLibrary. as well as allPermission & I've tried a whole host of variations along those lines all to no avail producing the following error trace in the Java Console:
java.lang.ExceptionInInitializerError
at app.TestApplet.LogAString(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.plugin.javascript.JSInvoke.invoke(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.plugin.javascript.JSClassLoader.invoke(Unknown Source)
at sun.plugin.com.MethodDispatcher.invoke(Unknown Source)
at sun.plugin.com.DispatchImpl.invokeImpl(Unknown Source)
at sun.plugin.com.DispatchImpl$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin.com.DispatchImpl.invoke(Unknown Source)
Caused by: java.security.AccessControlException: access denied (java.lang.RuntimePermission loadLibrary.DLoggerImpl)
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkLink(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
at app.DLogger.<clinit>(Unknown Source)
... 16 more
java.lang.Exception: java.lang.ExceptionInInitializerError
at sun.plugin.com.DispatchImpl.invokeImpl(Unknown Source)
at sun.plugin.com.DispatchImpl$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin.com.DispatchImpl.invoke(Unknown Source)
The key line seems to be "Caused by: java.security.AccessControlException: access denied (java.lang.RuntimePermission loadLibrary.DLoggerImpl)" which implies a permissions problem. It could be that I'm getting the policy file wrong - or the signing wrong - or stuff like that or it could be that Java is hardwired to not allow those sort of permissions for an Applet because of the security risk.
My question is am I wasting my time? Can it be done & if so, how?
Thanks in anticipation
Mike

You can definitely accomplish this. I have a working applet in production that does exactly this. Even if your applet is signed, you still need to use the Access Controller to access the dll, you cannot just call "loadlibrary". You can add this to the Java policy file however this is not recommended due to 1. You probably do not have access to the users java configuration. 2. Even if this is for your own company use, managing the policy file is a pain as users will download some JRE and your policy file is either overwritten or ignored.
You best bet is to sign your jar, making sure to wrap your load library code in a privileged block of code like this.
try
{
AccessController.doPrivileged(new PrivilegedAction()
{
public Object run()
{
try
{
// privileged code goes here, for example:
System.load("C:/Program Files/.../Mydll.dll");
return null; // nothing to return
}
catch (Exception e)
{
System.out.println("Unable to load Mydll");
return null;
}
}
});
}
catch (Exception e)
{
System.out.println("Unable to load Mydll");
}
You can Also use System.loadlibrary(mydll.dll) but you have to have the dll folder on the path in windows so the applet can find it.
If you need some source samples for calling the JNI functions let me know I can grab that as well.

The only thing I can suggest is taking a look at the source code for that area and trying to decipher if it is not allowing because of lack of permission or because that is not allowed at all. You don't have line numbers unfortunately, so that makes it a little more tricky.

I am pretty sure you cannot load a native library from an Applet unless it is "signed", and then the user will get an acceptance dialog to allow or disallow. That is, assuming you can do JNI at all in an applet... never tried that.
Good luck.

Related

Additional Permission required if Java Console is open?

I've found an interesting behaviour in my Java Applet.
All seems to work fine, but when i have the Java Console Window the Applet does nothing and i can see the following exception to be thrown in the Java Console:
Exception in thread "Thread-33" java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.com.sun.deploy.uitoolkit.impl.awt.ui")
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPackageAccess(Unknown Source)
at sun.plugin2.applet.SecurityManagerHelper.checkPackageAccessHelper(Unknown Source)
(...)
So my question is now, why does the Application need more permissions when the console is open than when its closed? I've tried to google the permission but no one seems to have had any problems with this.

applet with swing mysql and a config file works in eclipse but fails in browser

Hi it's probably because i'm a noob, but i'm trying to get this working for days now so hope that someone can help me....
The idea:
For a java training i need to make a Java applet that reads and writes data from a (localhost) MySQL database. The settings from this database have to come out of a config.ini file.
The application runs fine as an applet and a java application in Eclipse.
It also runs fine as an executable jar file.
I can't get it running as an applet though...:(.
The first error that i got was about reading the config.ini file. I expect that this happens because of the security limitations (io). It is something that needs to be solved but not my main concern for now.
In order to see if the rest works i skip my loadIni class. Then i got a: driver not found exception.
I solved this by loading the mySQL jar as an archive in my applet ().
But now i'm lost...
When i start the applet in the browser i get the following error in the console:
java.lang.RuntimeException: java.lang.ExceptionInInitializerError
at com.sun.deploy.uitoolkit.impl.awt.AWTAppletAdapter.instantiateApplet(Unknown Source)
at sun.plugin2.applet.Plugin2Manager.initAppletAdapter(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ExceptionInInitializerError
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:327)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at Kreta.DBConnection.<init>(DBConnection.java:39)
at Kreta.AfhaalMenus.<init>(AfhaalMenus.java:21)
at Kreta.test2.<init>(test2.java:39)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at com.sun.deploy.uitoolkit.impl.awt.AWTAppletAdapter$1.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.security.AccessControlException: access denied ("java.util.PropertyPermission"
"file.encoding" "read")
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at sun.plugin2.applet.AWTAppletSecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPropertyAccess(Unknown Source)
at java.lang.System.getProperty(Unknown Source)
at com.mysql.jdbc.StringUtils.<clinit>(StringUtils.java:70)
... 31 more
I really hope that somebody can send me in the right direction.
Applets are not allowed to do a number of things, including file I/O and various networking tasks; as your applet is trying to do one. You may need to sign you applet.
Check this reference
http://www.coderanch.com/how-to/java/HowCanAnAppletReadFilesOnTheLocalFileSystem
The answer is signing all jars.
how to do this was still a quest but the following post made it really easy:
how do i sign a java applet
An applet should not have direct access to the DB. This is for the security of the DB. Instead it should be forced to go through a web service that (limits what the user can do &) itself interacts with the DB.
An applet communicating with a DB (or a web service) on the same host that served it can be sand-boxed.
If that 'reading properties' error is part of the DB connection code you do not control, that is a good case for hiding the DB access behind the web service. Otherwise there are ways of reading a properties file (from the originating server) that do not invoke an AccessControlException.
Having said all that, it is getting to the stage where unsigned code is likely to be blocked before it is ever loaded, so perhaps the first thing you should do is digitally sign the applet and all required libraries.
Why code an applet? If it is due to spec. by teacher, please refer them to Why CS teachers should stop teaching Java applets. This will be easier to do with a standard desktop app. launched using Java Web Start. The security environment will be the same, but a free-floating app. is:
A better experience for the end user.
A lot easier to code and maintain than an applet embedded in a web page.

Jena + Pellet + Slick in an applet

I am trying to integrate Jena libs, Pellet and some RPG 2d library Slick all together in an applet.
So basically when I run the applet in the browser I get this file permission error (the jars I am using are all signed):
Exception in thread "Thread-15" java.lang.ExceptionInInitializerError
at org.mindswap.pellet.ABox.<init>(ABox.java:208)
at org.mindswap.pellet.KnowledgeBase.clear(KnowledgeBase.java:540)
at org.mindswap.pellet.KnowledgeBase.<init>(KnowledgeBase.java:418)
at org.mindswap.pellet.jena.PelletInfGraph.<init>(PelletInfGraph.java:99)
at org.mindswap.pellet.jena.PelletReasoner.bind(PelletReasoner.java:95)
at org.mindswap.pellet.jena.PelletReasoner.bind(PelletReasoner.java:53)
at com.hp.hpl.jena.ontology.impl.OntModelImpl.generateGraph(OntModelImpl.java:2744)
at com.hp.hpl.jena.ontology.impl.OntModelImpl.<init>(OntModelImpl.java:139)
at com.hp.hpl.jena.ontology.impl.OntModelImpl.<init>(OntModelImpl.java:128)
at com.hp.hpl.jena.rdf.model.ModelFactory.createOntologyModel(ModelFactory.java:410)
at RPGGame.GameSelectionScreen.init(GameSelectionScreen.java:170)
at RPGGame.RPGGame.initStatesList(RPGGame.java:39)
at org.newdawn.slick.state.StateBasedGame.init(StateBasedGame.java:164)
at org.newdawn.slick.AppletGameContainer$Container.initApplet(AppletGameContainer.java:272)
at org.newdawn.slick.AppletGameContainer$ContainerPanel.initGL(AppletGameContainer.java:229)
at org.newdawn.slick.AppletGameContainer$ContainerPanel.start(AppletGameContainer.java:216)
at org.newdawn.slick.AppletGameContainer$1.run(AppletGameContainer.java:92)
Caused by: java.security.AccessControlException: access denied ("java.util.PropertyPermission" "pellet.configuration" "read")
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPropertyAccess(Unknown Source)
at java.lang.System.getProperty(Unknown Source)
at org.mindswap.pellet.PelletOptions.<clinit>(PelletOptions.java:805)
Thanks in advance,
Ioana
The error is because ABox is trying to read information out of PelletOptions, which needs to load the Pellet configuration. It will usually try to read this out of the jar, but first, it double checks if the user specified in the system properties a different location than the default. It's this check that is causing the error.
You can just modify PelletOptions to always check in the jar and avoid the system properties check, or you might be able to twiddle the applet security stuff to make this ok (I don't know if that's possible, never used an Applet before).

"access denied" when using JDBC from a browser applet

I have a java applet that queries an Oracle database for data. When run from inside an IDE, it functions just fine. But when I run it as an applet embedded in a webpage, I get an "access denied" error in the class loader, and I haven't the foggiest notion what it is requiring of me:
Sep 06, 2011 12:58:48 PM oracle.jdbc.driver.OracleDriver registerMBeans
WARNING: Error while registering Oracle JDBC Diagnosability MBean.
java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "getClassLoader")
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.Thread.getContextClassLoader(Unknown Source)
at oracle.jdbc.driver.ClassRef.<init>(ClassRef.java:75)
at oracle.jdbc.driver.ClassRef.newInstance(ClassRef.java:51)
at oracle.jdbc.driver.OracleDriver.registerMBeans(OracleDriver.java:311)
at oracle.jdbc.driver.OracleDriver$1.run(OracleDriver.java:199)
at java.security.AccessController.doPrivileged(Native Method)
at oracle.jdbc.driver.OracleDriver.<clinit>(OracleDriver.java:195)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at com.binderton.oracle.ConnectionManager.open(ConnectionManager.java:17)
at com.sun.javafx.applet.FXApplet2$2.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl$3.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(Unknown Source)
at com.sun.glass.ui.win.WinApplication$1$1.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at com.binderton.oracle.ConnectionManager.open(ConnectionManager.java:17)
at com.sun.javafx.applet.FXApplet2$2.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl$3.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(Unknown Source)
at com.sun.glass.ui.win.WinApplication$1$1.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" getClassLoader")
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.Thread.getContextClassLoader(Unknown Source)
at oracle.jdbc.driver.ClassRef.<init>(ClassRef.java:75)
at oracle.jdbc.driver.ClassRef.newInstance(ClassRef.java:51)
at oracle.jdbc.driver.OracleDriver.<clinit>(OracleDriver.java:260)
... 12 more
Got ErrorEvent[url=null label=Failed to start application. cause=null
Applets runs in an environment with very restrictive security rules. You need at least to sign your applet.
But, the problem is bigger here, doing JDBC inside an applet is a very bad idea. The applet's source code is publicitly available and is thus sensitive for easy hacks. You should really create a webservice for that instead and then let your applet access that webservice instead. With a webservice, your applet will be able to exchange information with the DB by just HTTP requests/responses. With a webservice you hide the DB access details, JDBC and SQL code from the public.
How exactly to create a webservice depends on the server environment and the programming language used. In Java EE for example, you could already use a simple Servlet for this, but also JAX-RS and JAX-WS is supported for restful (XML/JSON) and XML webservices respectively. An applet is without any security restrictions allowed to connect with its host whose address is available by getCodeBase() E.g.
InputStream response = new URL(getCodeBase(), "servlet?foo=bar").openStream();
// ...
Note that if you follow the advice of BalusC and hide the DB behind a an active page (e.g. a servlet, PHP, ASP etc.) that is on the same server as the applet, the applet could most probably remain sand-boxed. It would be the active page that is trying to access class-loaders (as well as the DB).

java applet java.security.AccessControlException: access denied java.net.SocketPermission

I friend of mine gave me a script to run minecraft skins on my site but i keep getting this error and i dont have any clue how to go about this... =(
http://allcitybuilder.com/new/example.html
java.security.AccessControlException: access denied (java.net.SocketPermission www.minecraft.net:80 connect,resolve)
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkConnect(Unknown Source)
at sun.plugin2.applet.Applet2SecurityManager.checkConnect(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.<init>(Unknown Source)
at sun.net.www.http.HttpClient.New(Unknown Source)
at sun.net.www.http.HttpClient.New(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
at net.minecraft.skintest.math.Zombie$1.run(Zombie.java:82)
You must allow the Applet to connect to a resource.
Have a look at the sigend Applet tutorial: http://www-personal.umich.edu/~lsiden/tutorials/signed-applet/signed-applet.html
Normally Applets are only allowed to access the host they came from (in your case allcitybuilder.com). Thus, you either have to put the file to view also to this host (or install a proxy there), or your applet needs additional privileges to have more access.
For the applet to have more access, it needs to be digitally signed, and the user needs to confirm the applet loading.
But there is no way to say "I need only access to minecraft.net" and for the user to grant you only this permission (without manual editing of policy files), so it is an "all or nothing". Also, if the user refuses, the applet may either run with usual applet permissions (on Sun's Plugin) or not run at all (on IcedTea).
With JNLP you can get a confirmation for the user for individual actions, but this is only for local access, no remote one.
Probably the easiest thing would be to copy the resources to your site, making sure you have been granted appropriate rights by the copyright holder.
Alternatively, the site may add a crossdomain.xml file to allow access to code loaded from non-same-origin sites.
It is possibly to sign the code to gain full access to the local machine. However, this requires the user to accept the risk and writing secure code is surprisingly difficult.

Categories

Resources