Jython: Block access to java classes & Change output stream - java

I'm looking to use the Jython in a Java project I'm working on.
And I'm wondering 2 things.
Can I disable access to Java classes from Python scripts. IE. stop scripts from being able to do things like from java.util import Date?
And can I change the output stream that print "Hello" etc write to, so that I can redirect a scripts output for my implementation?
Or will I have to edit the actual Jython classes to disable and change this?

In order to restrict access to specific Java classes you could implement a custom class loader and register it to Jython:
this.pyInterpreter.getSystemState().setClassLoader(this.userCodeClassLoader);
If you are doing this because of security issues (disallow some actions on server machine that runs user code) you have to notice that Jython also provides built-in function implementations that won't be caught by your class loader:
Built-in Python function implementations

One additional approach is to analyze all imports in Python parse tree. I think it's better having more than one security measure:
String code = "import sys\n"+"from java.io import File\n"+"sys.exit()";
AnalyzingParser anPar = new AnalyzingParser(new ANTLRStringStream(code), "", "ascii");
mod tree=anPar.parseModule();
Visitor vis = new Visitor() {
#Override
public Object visitImport(Import node) throws Exception {
System.out.println(node);
return node;
}
#Override
public Object visitImportFrom(ImportFrom node) throws Exception {
System.out.println(node);
return node;
}
};
List<PythonTree> children=tree.getChildren();
for (PythonTree c : children){
vis.visit(c);
}

Related

Import classes in method?

I'm customizing a PLM Windchill Workflow, which provides a mechanism to execute java code snippets. Unfortunately, they are 'inserted' into prepared service's method, which means that there is no way to import classes, so I have to include full package names to use it. Don't try to understand the snippet below, just look how does it looks like:
wt.fc.QueryResult activities = wt.fc.PersistenceHelper.manager.find((wt.pds.StatementSpec) activitiesQuery);
while (activities.hasMoreElements()) {
wt.workflow.work.WfAssignedActivity activity = (wt.workflow.work.WfAssignedActivity) activities.nextElement();
if(activity.getDisplayIdentifier().toString().equals("Analyze Image Request")){
java.util.List<wt.workflow.work.WorkItem> workItems = wt.workflow.status.WfWorkflowStatusHelper.service.getWorkItems(activity);
for (wt.workflow.work.WorkItem workItem : workItems){
String action = workItem.getActionPerformed();
if(action != null && action.equals("Accepted")){
wt.org.WTPrincipalReference approver = workItem.getOwnership().getOwner();
n_approver = approver.getFullName() + " ("+approver.getDisplayName()+")";
wt.fc.collections.WTHashSet approverSet = new wt.fc.collections.WTHashSet(java.util.Arrays.asList(approver));
wt.project.Role role = wt.project.Role.toRole("APPROVER");
com.ptc.windchill.pdmlink.change.server.impl.WorkflowProcessHelper.setChangeItemParticipants(report, role, approverSet);
break;
}
}
break;
}
}
And my question is - how to make this code any more readable? Of course there is no way to import classes inside the method, there is even no way to divide this snippet into separate methods (as it is 'pasted' into one) so I'm looking for other ideas.
One option to make the code more readable would be to separate chained method/property calls across multiple lines.
For example, this line:
wt.project.Role role = wt.project.Role.toRole("APPROVER");
could be rewritten as:
wt.project.Role role = wt
.project
.Role
.toRole("APPROVER");
You can call this complete code from a Customized Java class.
You just have to call your class and take the final parameters required from the Java class to make it more readable.
If you need multiple outputs write multiple methods in Java class and call them in workflow expression.
You can't.
Workflows expressions are methods bodies.
A statement like
wt.fc.QueryResult activities = wt.fc.PersistenceHelper.manager.find((wt.pds.StatementSpec) activitiesQuery);
ends in a class under $WT_HOME/codebase/wt/workflow/expr/
with a method :
public static Object executemethod_1(Object[] var0, Object[] var1) throws Exception {
wt.fc.QueryResult activities = wt.fc.PersistenceHelper.manager.find((wt.pds.StatementSpec) activitiesQuery);
// some generated code to handle variables...
}
So, you can't use import.
However :
If you have a PDMLink version greater than 10,
You can externalize workflow expression
http://support.ptc.com/cs/help/windchill_hc/wc100_hc/index.jspx?id=WFTemplateExtExpression&action=show
This create a java class under /codebase/ext/wt/workflow/externalize
Then you can do what you want, but you'll have to compile these classes, and do a stop/start in case of modifications.
Basically, it's nothing more than calling external code from the expression, so I don't use it a lot...

In Java and using Bridj, how can you dynamically invoke any native function?

Often users of Clojure wish to be as lazy as possible, and delay the creation of classes and objects. In that same spirit, if I wish to invoke a native function which is resolved during runtime from within Java, I can use com.sun.jna.Function.getFunction("foolibrary", "foofuncname"), which returns a com.sun.jna.Function, which can be invoked.
In Clojure this looks like:
(let [f (com.sun.jna.Function/getFunction "c" "printf")]
(.invoke f Integer (to-array ["Hello World"])))
BridJ, on the other hand, offers an attractive performance benefit and claimed simplier API, however, it is still not clear to me how to use BridJ to do something similar to the runtime binding JNA example. Can someone demonstrate how? Also, if this is possible, are there any performance penalties with this approach? Otherwise, it appears generating the Java source file ahead of time is the only solution. I would appreciate it if someone could confirm this.
Edit:
After better understanding the question & focusing on "dynamically" (without pre-compilation), I still hesitate to claim "it is impossible" ("impossible" is a very strong word/meaning ...like "always"/"never"), but I am very sure that this is not the standard routine of BridJ.
I can think of a dynamical solution with Bridj, but this would be very probably dependent from "JNAerator" and this in turn would be dependent from "JNA" (your starting position).
The original answer, describing the "standard routine" for "dynamically invoke any native function with BridJ" (involving code generation):
According to https://code.google.com/p/bridj/ and https://code.google.com/p/bridj/wiki/FAQ, you'll have to:
Set up a bridJ project (java project + bridJ dependencies)
Run the JNAerator (with bridJ output option) against your libs. This will generate Java files, which serve as "stubs/delegates" for your exported functions.
These "stubs" can be referenced/used by your java code, and (should) invoke your libs.
Sample taken from "their Quickstart":
Original C++ code :
/// exported in test.dll / libtest.so / libtest.dylib
class MyClass {
public:
MyClass();
~MyClass();
virtual void virtualMethod(int i, float f);
void normalMethod(int i);
};
void getSomeCount(int* countOut);
...
void test() {
int count;
getSomeCount(&count);
MyClass t;
t.virtualMethod(count, 0.5f);
}
Translation + binding with BridJ :
(this is generated java code)
import org.bridj.*; // C interop and core classes
import org.bridj.ann.*; // annotations
import org.bridj.cpp.*; // C++ runtime
import static org.bridj.Pointer.*; // pointer factories such as allocateInt(), pointerTo(java.nio.Buffer), etc...
#Library("test")
public class TestLibrary {
static {
BridJ.register(); // binds all native methods in this class and its subclasses
}
public static class MyClass extends CPPObject {
#Virtual(0) // says virtualMethod is the first virtual method
public native void virtualMethod(int i);
public native void normalMethod(int i);
};
public static native void getSomeCount(Pointer<Integer> countOut);
public static void test() {
Pointer<Integer> pCount = allocateInt();
getSomeCount(pCount);
MyClass t = new MyClass();
t.virtualMethod(pCount.get(), 0.5f);
}
}
Hope this helps!

Python equivalence to org.apache.commons.configuration?

I want to port this Configuration.class object (from http://pastebin.com/dZeV27XB) into python and it seems hard to port the org.apache.commons.configuration object
In the java class, there were multiple functions that returns a Configuration.getString or Configuration.getInt e.g.
public int getDumpEndDir()
{
return this.config.getInt("wiki.dump.endDir");
}
public String getDocDir()
{
return this.config.getString("wiki.dump.docDir");
}
Any clue to what such function return?
Is there a python library similar to org.apache.commons?
Especially if there is one with the org.apache.commons.configuration library.
Is there a reason why this is in Java but not python?
You can use python's inbuild ConfigParser module which is very similar to Java's properties file loader. But here, the configuration parameters will be split section-wise.
check this,
https://docs.python.org/2/library/configparser.html
If it is an inmemory config structure, then you can simply use a dictionary object...

How to link to a package but only optionally execute an action based on existence/availability of package at runtime?

From the perspective of a cross application/applet java accessibility service, how would you link to a package but only optionally execute an action based on existence/availability of a package (being already loaded) at runtime?
I think what I'm interested in here is a way to resolve the class identity crisis but rather than the issue being between 2 apps sharing objects, being a service loaded at a higher level of the class loaders.
It seems like reflection is the way to go, but I am not sure how or if I can implement a derived class this way. I need to add a specific listener derived from the specific optional classes, I can load the listener using the applet class loader but the internals still fail. Say you wanted to add an JInternalFrameListener, but Swing wasn't guaranteed to be available, using reflection you can find the method to add the listener, but how can you create and have the frame listener work if it cannot find any of the related classes because they can't be found in the base classloader! Do I need to create a thread and use setContextClassLoader to the classloader that knows about swing so that I can get the class to be loaded reliably? simply trying to set the class loader on my existing thread didn't seem to work.
Earlier description of issues
Sorry, I'm not quite sure what to ask or how to make this clear, so it rambles on a bit.
Say a class uses some feature of another, but the other class may not always be available - say finding the website from JNLP if this is a JNLP app.
At one stage I thought that simply compiling against JNLP would mean that my class would not load unless JNLP was available, and so to identify this optional section I simply wrapped a try{} catch( NoClassDefFoundError ) around it.
Later something changed (perhaps changing jdk or ?? I don't recall) and it seemed that I should also use a try{} catch( ClassNotFoundException ).
Now I wanted to extend this idea to other optional features, but it doesn't seem to work consistently.
Say I wanted to add some feature to do something more advanced in a JRE1.6 runtime using the same jar and classes as I run in a JRE1.3, or say I want to handle some controls in a specific gui toolkit which may not always be used like SWT or oracle.forms.
Is there some way of doing this more reliably? It just seems wrong to cause an exception and catch it to ignore it all the time.
The current issue comes down to being able to compile against oracle.forms but then the accessibility component installed in ext is unable to access the oracle.forms classes even though objects from the oracle.forms package have been created. If I throw the frmall.jar into the ext directory to test then the accessibility component works up to the point that the whole lot gets flakey because of the different versions of the same package.
I seem to be caught up on an issue with the class loader not being the right one or something (??). How do I find the right one?
Edit:
The answers so far are kindof interesting but not quite getting me where I want to be.
In the case of the gui components I currently compile in the form of a factory something like...
import oracle.forms.ui.*;
import java.awt.*;
static public IComponentNode newNode( INode parent, Component component ) {
System.out.println( component.getClass().toString() );
try{
if( component instanceof FormDesktopContainer )
... does stuff here like return new FormDesktopNode( parent, (FormDesktopContainer) component )
} catch ( NoClassDefFoundError a ) {
System.out.println( a.getMessage() );
}
where it prints out class oracle.forms.ui.FormDesktopContainer and then throws and exception on the instanceof call with NoClassDefFound thus printing out oracle/forms/ui/FormDesktopContainer
So how can it have an instance of a class yet not be able to find it?
How about this? messy, but it ought to work:
public boolean exists(String className){
try {
Class.forName(className);
return true;
}
catch (ClassNotFoundException){
return false;
}
}
You can check the availability of a class by calling
ClassLoader.getSystemClassLoader().loadClass("my.package.MyClass")
if it throws a ClassNotFoundException, it's not available. If you get the Class object, it is. You can then choose behaviour based on whether or not the class is available.
I suggest compiling the majority of your code against your minimum target. Have code that uses particular optional libraries clearly separated, but dependent upon the bulk of your code. Dynamically load the code that uses optional libraries once. The main class should do something that checks for the presence of the required library/version in its static initialiser.
In the case of JNLP, your JNLP main class load the JNLP dependent code statically.
(Note that attempting to catch class loading related exceptions from normally linked code is unreliable.)
getSystemClass loader was not useful for this purpose as there where multiple possible class loaders to interact with based on which applet the given window was in. The accessibility components being loaded at a more base class loader cannot see the applet specific classes.
To interact with the objects reflection does the job, though it does add so much more to maintain.
// statically linking would be
return component.getText();
// dynamically is
try {
return (String)component.getClass().getMethod("getText", new Class [] {}).invoke(component, new Object [] {});
} catch (Throwable e) {
e.printStackTrace();
}
The trickier bit is in writing a class derived from an interface that is not directly accessible, using the Proxy service allows this to be accomplished, providing the proxy service the applet specific class loader and the dynamically loaded class for the interface.
public void addListener(Container parent) {
if (parent == null) { return; }
if ("oracle.forms".equals(parent.getClass().getName())) {
// Using the class loader of the provided object in the applet
// get the "class" of the interface you want to implement
Class desktopListenerClass = Class.forName( "oracle.DesktopListener"
, true, parent.getClass().getClassLoader());
// Ask the proxy to create an instance of the class,
// providing your implementation through the InvocationHandler::invoke
Object desktopListener = Proxy.newProxyInstance(
parent.getClass().getClassLoader()
, new Class[] { desktopListenerClass }, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if ("functionName".equals(method.getName())) {
// do stuff
}
return null;
}
});
// do something with your new object
Method addDesktopListener = parent.getClass().getMethod("");
addDesktopListener.invoke(parent, desktopListener);
}
}
examples cut down to show general method

How can I convince GroovyShell to maintain state over eval() calls?

I'm trying to use Groovy to create an interactive scripting / macro mode for my application. The application is OSGi and much of the information the scripts may need is not know up front. I figured I could use GroovyShell and call eval() multiple times continually appending to the namespace as OSGi bundles are loaded. GroovyShell maintains variable state over multiple eval calls, but not class definitions or methods.
goal: Create a base class during startup. As OSGi bundles load, create derived classes as needed.
I am not sure about what you mean about declared classes not existing between evals, the following two scripts work as expected when evaled one after another:
class C {{println 'hi'}}
new C()
...
new C()
However methods become bound to the class that declared them, and GroovyShell creates a new class for each instance. If you do not need the return value of any of the scripts and they are truly scripts (not classes with main methods) you can attach the following to the end of every evaluated scrips.
Class klass = this.getClass()
this.getMetaClass().getMethods().each {
if (it.declaringClass.cachedClass == klass) {
binding[it.name] = this.&"$it.name"
}
}
If you depend on the return value you can hand-manage the evaluation and run the script as part of your parsing (warning, untested code follows, for illustrative uses only)...
String scriptText = ...
Script script = shell.parse(scriptText)
def returnValue = script.run()
Class klass = script.getClass()
script.getMetaClass().getMethods().each {
if (it.declaringClass.cachedClass == klass) {
shell.context[it.name] = this.&"$it.name"
}
}
// do whatever with returnValue...
There is one last caveat I am sure you are aware of. Statically typed variables are not kept between evals as they are not stored in the binding. So in the previous script the variable 'klass' will not be kept between script invocations and will disappear. To rectify that simply remove the type declarations on the first use of all variables, that means they will be read and written to the binding.
Ended up injecting code before each script compilation. End goal is that the user written script has a domain-specific-language available for use.
This might be what you are looking for?
From Groovy in Action
def binding = new Binding(x: 6, y: 4)
def shell = new GroovyShell(binding)
def expression = '''f = x * y'''
shell.evaluate(expression)
assert binding.getVariable("f") == 24
An appropriate use of Binding will allow you to maintain state?

Categories

Resources