I'm trying to build a plugin that needs the following permissions:
grant {
permission java.lang.RuntimePermission "accessDeclaredMembers";
};
When I install the plugin I get the warning saying that the plugin asks for permissions (which means the installation sees the above) but then when I try to use the plugin I get an error saying:
Yes I have. I have my code in a doPrivileged block but it's not changing anything.
public int analyzeSentiment(String text){
return AccessController.doPrivileged(new PrivilegedAction<Integer>() {
public Integer run(){
StringByValue str = new StringByValue();
str.setP(text);
str.setN(text.length());
return gs.ClassifySentiment(str);
}
});
}
PS: I think the ES docs for plugins (for authors) have to be a lot more expansive than they are. There is barely any documentation for it apart from the page you linked and the 4 examples linked in it.
Yes. When it installs I get the big warning with all the @ symbols. However I'm using docker so there's no stdin so I'm using the -b flag for the installation (don't think that makes a difference). Then I get a message saying successfully installed *plugin_name*. I also checked the actual build to make sure the file is there. I'm running out of ideas here.
The way to read this is to look at the failing stack, back to the doPrivileged call:
access: access denied ("java.lang.RuntimePermission" "accessDeclaredMembers")
java.lang.Exception: Stack trace
at java.base/java.lang.Thread.dumpStack(Thread.java:1387)
at java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:462)
at java.base/java.security.AccessController.checkPermission(AccessController.java:895)
at java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:322)
at java.base/java.lang.Class.checkMemberAccess(Class.java:2848)
at java.base/java.lang.Class.getDeclaredFields(Class.java:2247)
at com.sun.jna.Structure.getFieldList(Structure.java:931)
at com.sun.jna.Structure.validateFields(Structure.java:1160)
at com.sun.jna.Structure.<init>(Structure.java:189)
at com.sun.jna.Structure.<init>(Structure.java:182)
at com.sun.jna.Structure.<init>(Structure.java:169)
at com.sun.jna.Structure.<init>(Structure.java:161)
at de.spinscale.elasticsearch.ingest.sentiment.GoString.<init>(GoString.java:16)
at de.spinscale.elasticsearch.ingest.sentiment.SentimentAnalyzer.lambda$analyzeSentiment$0(SentimentAnalyzer.java:41)
at java.base/java.security.AccessController.doPrivileged(Native Method)
Everything on that stack must have permission. Later in the log, we see exactly what doesn't have permission:
access: domain that failed ProtectionDomain (file:/usr/share/elasticsearch/lib/jna-4.5.1.jar <no signer certificates>)
The problem is jna is a jar provided by elasticsearch, and your bare grant statement only applies to jars provided by your plugin. Unfortunately there isn't currently a way for a plugin to extend the permissions of core jars.
I see three possible solutions:
Modify your code to not use jna
Modify your jna usage to not trigger accessDeclaredMembers (note that this means you are getting all private/protected variables and methods, is this really necessary, or do you just need public?)
Set the system policy to give jna access (elasticsearch builds on this policy if it exists). This will be tricky, as you need to give the exact path to the jna jar within the elasticsearch installation. It would look something like this:
grant codeBase "/usr/share/elasticsearch/lib/jna-4.5.1.jar" {
permission java.lang.RuntimePermission "accessDeclaredMembers";
}
Note however that this is extremely fragile: it can and will change as elasticsearch in upgraded, so the first two options are much better, but this might get you by temporarily.
Just tried option 3 and it doesn't work. The debug log is pretty much the same. Also I think it should be:
grant codeBase "file:/usr/share/elasticsearch/lib/jna-4.5.1.jar" {
permission java.lang.RuntimePermission "accessDeclaredMembers";
}
Without the file: prefix it gives me an error about a malformed URL and with it, it seems like it doesn't recognize it because I'm not getting the warning when installing the plugin now.
Regarding the second option, I'm not explicitly calling any protected or private code myself. I'm just inheriting a class from JNA which apparently has some protected/private methods (including the constructor) so I can't even use it as a superclass. It sucks that this is so hard to do
I'm not going to use JNA anymore. I found a decent alternative but I have to execute a binary. I changed the security permissions and I'm now getting a nullpointerexception because ES apparently doesn't have permission to execute the file (even though I gave it read and execute perms):
exception: java.io.IOException: Cannot run program "/usr/share/elasticsearch/bin/ingest-opennlp/sentiment": error=13, Permission denied
Apache, Apache Lucene, Apache Hadoop, Hadoop, HDFS and the yellow elephant
logo are trademarks of the
Apache Software Foundation
in the United States and/or other countries.