Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
adante
Sep 18, 2003
Hi, I am fiddling with the java scripting interface. As I understand the rhino engine is packaged with the jdk but what I don't understand is how does one reconcile the objects one gets from their engine (e.g. sun.org.mozilla.javascript.internal.ScriptableObject) versus the ones in the rhino api (e.g. org.mozilla.javascript.ScriptableObject)?

Is the one in the jdk heavily modified or wrappered up to suit their javax.scripting interface?

More specifically, how do I manipulate javascript objects from java?

e.g. suppose I have this java code:

code:
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine js = mgr.getEngineByName("js");
jsEngine.eval("var foo = { x : 1, y : 'hello', z : false };");
Object o = jsEngine.get("foo");
Now o is instanceof sun.org.mozilla.javascript.internal.NativeObject, which is a subclass of a bunch of other classes in the s.o.m.j.i namespace. Being internal I can't use these directly.

Looking at the Rhino API obviously you normally get a org.mozilla.javascript.ScriptableObject and can call the .get() .getIds() methods. But I don't know how to translate the objects I am getting in my actual java code which uses the jdk engine into org.mozilla.javascript objects.

Is this even possible? Am I misunderstanding something completely? Should I just be using the rhino js jar and not the javax.scripting interface? If so, for what reason is the javax.scripting interface implemented?

Adbot
ADBOT LOVES YOU

adante
Sep 18, 2003

TRex EaterofCars posted:

^^ You need to look up the javax.script.Bindings class. That is how you pass variables back and forth between a script and the host java program.

:confused: sorry, but can you give me a concrete example of what you mean? As far as I can tell getting the Bindings will allow me to get a java reference to the javascript object - but I already do this using the jsEngine.get("foo"). What I want to know is how do I manipulate it? For instance, how would I get a value given a key, or list the keys?

adante
Sep 18, 2003

TRex EaterofCars posted:

Bindings implements Map, so you'll be able to iterate over the entries just like Map:

code:
for (Map.Entry<String,Object> e:bindings) {
...do stuff...
}
.get() and .put() both work just like Map as well.

ok, I am feeling a little silly to ask this, but could you provide me with EXACT CODE WHICH WILL COMPILE to do what I want, because I cannot see how to apply the bindings method (which is an engine method to the object o in my previous code listing.

adante
Sep 18, 2003

hey wiz posted:

What else do you want, he pretty much gave you the code. If you want to iterate over each entry, probably you will want something like this:
ConcurrentModificationException.

well as I said, I basically want the exact code which will compile.

Either I have a fundamentally flawed view of the scripting API (and I am certainly not discounting this) or you guys are misunderstanding what I am asking for. I want to manipulate a javascript object by getting its keys and values.

The only way I can see how to use the code you guys have given me is to manipulate the javascript ENGINE, allowing me to get its variables. This is great, I got the variable I wanted, a javascript object, in my first post, under the code line which goes "Object o = jsEngine.get("foo");". Now I want to get the keys and values of that object.

I'm no expert with java and maybe you can use the Bindings class in a way to interrogate this object o. Unfortunately I have absolutely no idea how to do this because I cannot see any way to get a Bindings object relevant to o.

Hence, I asked for some exact code which I could compile so that I could either figure out exactly how to use the bindings class (if this is infact the case) or confirm that there has been a misunderstanding and I need to clarify.

In order to hopefully clarify exactly what I want, here's a skeleton template:

code:
import java.io.*;
import java.util.*;
import javax.script.*;

public class test {

	public static void main(String [] args) throws Exception
	{
		
        // TODO code application logic here
		ScriptEngineManager mgr = new ScriptEngineManager(); 
		ScriptEngine jsEngine = mgr.getEngineByName("js");
		jsEngine.eval("var foo = { x : 1, y : 'hello', z : false };");
		Object o = jsEngine.get("foo");
		
		interrogationFunction(o);
	}
	
	public static void interrogationFunction(Object o)
	{
		System.out.printf("Object is of type %s", o.getClass().getName());
		// implement me
	}
}
The objective is to implement the function interrogationFunction() to produce this output (or equivalent):

code:
This object has the following key/type/value pairs:
   x : java.lang.Double : 1.0
   y : java.lang.String : hello
   z : java.lang.Boolean : false
Just to show I am trying to make an effort here, the only way I can see how to implement the code you guys are suggesting is like this:

code:
		for (Map.Entry<String,Object> e: jsEngine.getBindings(ScriptContext.ENGINE_SCOPE).entrySet())
		{
			String key = e.getKey();
			Object value = e.getValue(); // equivalent to bindings.get(key) System.out.println("key: " + key + "\tvalue: " + value); }
			System.out.println("key: " + key + "\tvalue: " + value);
		}
Obviously this will get the engine variables, and produce this output:
code:
key: context	value: javax.script.SimpleScriptContext@b23210
key: foo	value: [object Object]
key: print	value: sun.org.mozilla.javascript.internal.InterpretedFunction@f4f44a

adante
Sep 18, 2003

hey wiz posted:

Let me see if I'm on the same page with you

key : this you are getting correctly.
type: this should be as simple as value.getClass().getName()
value: this is where you are stuck.
Actually I cannot get the key or list of keys either (maybe you can, if so please share how :dance: ).

hey wiz posted:

If you were working on simple classes such as String, Boolean, Double as you mentioned in the example, you could just print value.toString(). However, it seems like you are trying to print the value of Objects that don't have a friendly toString() method. These objects may still have a method which will print exactly what you want, but for each class it would be different. If this was the case, how would you determine which method to call on which class to print what you want?
the output I made is so that I could (hopefully) get a program that is a simple proof of concept to show how to access get the keys/values in the object. I don't actually want to print those variables.

As to how to figure out the type and so forth of the values - well I will deal with that after I figure out how to get the values :). As I understand it js is basically variable/object/functions anyway - variables map to string/bool/double, and if I figure out how to manipulate objects (1st part of the problem) then that is solved, which leaves functions to deal with.

TRex EaterofCars posted:

The problem comes when you try to do this poo poo in Java, because you can't even import sun.org.mozilla.javascript.internal.ScriptableObject, at least not with my JDK. You could probably get rhino and cast to whatever ScriptableObject Rhino provides and get() from there. It's a mess and you might want to write a wrapper class for it that implements Map, because honestly this is pretty worthless as it is.

Unfortunately you cannot cast it (or I cannot figure out how to):

code:
        js.eval("var asdf = {a:1, b:'asdf', c:false};");
        Object aaa = js.get("asdf");
        org.mozilla.javascript.NativeObject s = org.mozilla.javascript.NativeObject)aaa;
will throw a ClassCastException. Same thing happens if you cast to a omj.ScriptableObject :bang:

TRex EaterofCars posted:

groovy
wow, I had no idea this existed. Very cool, but unfortunately switching to another language is probably overkill at the moment :)

adante
Sep 18, 2003
Howdy, if I have some Class<?> object (in my case, returned from a Field#getType() during reflection), how can I tell if the class represented by this object implements a particular interface or class? I guess this is the equivalent to the instanceof operator, except for the class type and not an object.

e.g.:

code:
public class test4 {

	public class A implements C { }
	public class B extends A {}
	public interface C {}
	
	public static void main (String [] args)
	{
		test4 t4 = new test4();
		B b = t4.new B();
		
		if (b instanceof A) System.out.println("b instanceof a");
		if (b instanceof C) System.out.println("b instanceof c");
		
		Class<?> bClass = b.getClass();
		
		if (bClass == B.class) System.out.println("bClass is B.class");
		
		// what do I do here to determine if bClass implements or extends A,C or even B or any arbitrary class?
	}
}
I couldn't seem to find a way to do this with a nice and clean single method call and this surprised me. I wrote a function which seems to do the job but as I'm new to reflection and do not really trust my code if there IS an api method it'd naturally be preferable.

code:
	public static boolean implementsClass(Class<?> type, Class<?> clasz)
	{
		do {
			if (type == clasz)
				return true;

			for (Class<?> ifc : type.getInterfaces())
				if (ifc == clasz)
					return true;

			type = type.getSuperclass();
		} while (type != null);
		
		return false;
	}

adante
Sep 18, 2003

zootm posted:

what you want is Class.isAssignableFrom( Class<?> ).
too easy! thanks.

Another question: I am doing something which is probably insane and stupid where I have an abstract base class with a method that reflects on itself, collects all the fields and does many strange things with them (for the sake of this example, suppose the function prints them out)

The idea is I can then extend this class and add new fields, and then call the method which will print these newly added fields. However I want to automate this so that the method is called as soon as the object is instantiated!

I tried throwing this in the constructor of the abstract class but this is called before the derived class is instantiated.

So at the moment I have to instantiate the class, then call the method explicitly. I'm just wondering, is there a normal pattern for handling this (maybe with factory methods?) or am I just silly/insane for wanting to do it in the first place?

Some example code to hopefully explain the problem. The A() constructor calls reflect(), but the B fields are not yet initialized. When you call it after B() has finished it is fine, but I am anal and do not want to do this explicitly if possible.
code:

import java.lang.reflect.*;

public class test5 {

	public static void main (String [] args)
	{
		B b = new B();
		b.reflect();
	}
}

abstract class A {
	public A() {
		System.out.println("A constructor");
		reflect();
	}
	
	public void reflect()
	{
		for (Field f : this.getClass().getFields())
			try {
			System.out.println(f.getName() + " : " + f.get(this));
			} catch (IllegalAccessException e) {}
	}
}

class B extends A {
	public B() { System.out.println("B constructor"); }
	public String B_STRING = "hello this is B_STRING";
}

adante
Sep 18, 2003
hi, I want to readLine() from multiple BufferedReaders and do the same thing with the result (after some transforms, depending on the specific BufferedReader instance.

Is there a better way of doing it than instantiating a thread for each reader?

e.g. what I do now (this code is just written of the top of my head, but hopefully illustrates the point):
code:
for (BufferedReader br : listOfReaders)
{
	new Thread() {
		public void run() {
			String s = br.readLine()
			// stuff here
			DoThing(s);
		}
	}.start();
}
DoThing() is expected to do its business quite quickly so having inputs pile up is not a big issue.

FWIW the BufferedReaders are based on InputStreams. I was thinking of trying to do something with the InputStream#available() method but I can't really think of anything obvious (un-obvious: re-implementing BufferedReader functionality in some sort of horrific BufferedReaderMultiplex?)

adante fucked around with this message at 20:28 on Aug 22, 2008

adante
Sep 18, 2003

Incoherence posted:

Depends how many readers you have relative to how long it takes for each one. If you have, say, a whole lot of readers, but for each one all you want to do is read a line, munge it a bit, and move on, the cost of starting that many threads may become a nontrivial portion of your runtime, at which point thread pools (java.util.concurrent.something) become an option.

This article is old, but explains what I just said in more detail: http://www.ibm.com/developerworks/library/j-jtp0730.html

Right, I'm familiar with thread pools to an extent but my question was more: how do I do it when readLine() is a blocking operation and there is (as far as I can see) no non-blocking alternative?

If you can provide some example code that, in a single thread, could check multiple BufferedReader#readLine() calls and service them/add them to a worker pool, I'd be interested in seeing it.

adante
Sep 18, 2003

Incoherence posted:

The example you give calls readLine() within a thread, so thread pools don't really change that problem. I didn't get the impression from your post that that was your big problem, but maybe I wasn't reading it closely enough. If the readers are all reading from the same place (disk, network), they're probably going to be queued by something anyway. (I'm pretty sure hard disks can't read 500 different files at once. Could be wrong, of course.) You may as well have threads processing while they're waiting for I/O, and you may as well use a thread pool since you really don't need to start up and tear down N threads just to keep busy while you wait for N readLine calls.

Basically, the only change I suggested is that instead of starting each "read, DoThing" task in its own thread, as your example does, you'd start each in a thread pool, which would have approximately the same result but wouldn't need to set up quite so many threads.

right, and what I meant is, I don't know how to do this. I don't see how it is possible to have N threads servicing M BufferedReaders where N < M. Maybe there is a misunderstanding here, but I think code speaks for itself. If you could provide some code/pseudocode that illustrates how to do this I'd be really interested.

adante
Sep 18, 2003

Incoherence posted:

That's kind of the idea behind a thread pool. Instead of creating M threads that do one task apiece (as your example does), you create a thread pool with N threads, and you add your M tasks to the thread pool. The thread pool is usually implemented as a producer/consumer setup: the thread pool controller has a queue of work to do, and as worker threads finish what they were doing before they get work from the queue.

In particular, what I think you want is this. This code sample is pretty close to what you're doing, I guess.

lol we're just going around in circles. I keep saying I don't know how to create a clean solution that services M BufferedReader's using < M threads because readLine() can block and there's no way to tell if it will; and you keep saying "use thread pools!".

Tell you what, if you can provide a solution (M BufferedReaders, <M threads) and implement it in this function, I'll paypal you $15.

code:
import java.io.*;

public abstract class Callback {

	public static void bindCallback(final BufferedReader[] brs, final Callback callback) {
	//implement me!
	}

	public abstract void service(String string);

}

FWIW I have a 1-thread solution which uses BufferedReader#ready() and semi-busy waiting but this does not work properly when the BufferedReader fills with data without a newline, so it doesn't count.

adante
Sep 18, 2003

triplekungfu posted:

adante, I'm fairly sure you'll need to create M readers, however you can service them with less than M threads.

I whipped this up for my own understanding, it might help point you in the right direction.

if you mean I'll need to create M reader threads, then yes I agree. Otherwise.. well I still agree but you are reiterating the problem spec :)

hey wiz posted:

I think you are missing the point adante. If you use a queue, even though you have multiple threads, it's only going to allow one thread to DoStuff() at a time, so you don't have to worry about readLine() blocking. To reiterate what Incoherence said, thread pools and a queue definately sound like the way to go.

Ok, MY point is that you guys keep suggesting I use a threadpool. Yes, a N-thread threadpool means my M threads will be very simple and the servicing goes into the N threads, but now I have M + N threads. This is not less than M threads. This is more than M threads! To re-iterate, my original question was if I could do it with less than M threads (well literally, 'Is there a better way of doing it than instantiating a thread for each reader?').

Either you are not answering my question, or you guys genuinely believe this can be done with less than M threads.

If the former, that is not so helpful.

If the latter then this argument is fast becoming academic. I will open up the $15 offer to anybody (paying out first correct solution only) so prove your point by implementing this and earn some easy cash. Rules apply (solution must be 'correct', use <M threads, no insane reflection tricks).

adante
Sep 18, 2003

zootm posted:

The non-blocking IO stuff in java.nio lets you deal with many inputs using very few Java threads. You stated before that you knew of no non-blocking alternative so there it is. It's not on Reader because Reader etc. predate all the non-blocking stuff they added in I think version 5. But really I'm kind of lost trying to figure out what all this bickering is about.

here's the cliff's notes from my point of view:

adante: I want to service M BufferedReaders using less than M threads [I do not explicitly state that I want it to work properly - as in all BufferedReaders being serviced regardless of input - but I kind of hoped it would be implied]

Incoherence(after some back and forth): Use threadpools!

hey wiz: Use threadpools!

triplekungfu: [I think he is saying you need M threads but I'm not sure] + Here is some threadpool code!

zootm: a threadpool with less than M threads will not service M BufferedReaders

Anyway, at this stage one persons opinion will do for me. let's consider the discussion closed. For pedagogic reasons I will keep the $15 offer open (and even provide a quick and dirty test/example) if you can re-implement bindCallback to use, say, 3 threads -- so go for it team threadpool, easy money to be made.

adante fucked around with this message at 01:04 on Aug 26, 2008

adante
Sep 18, 2003

triplekungfu posted:

No, that's not what I meant, in the example I gave earlier I had three threads servicing 15 objects.

I got bored and whipped this up. There's 5 threads servicing brs.length BufferedReaders.

looks like 5 threads performing a SINGLE service of 15 BufferedReaders, once each. It also looks like if the first 5 BufferedReaders are not written to, but the remainder are, nothing will ever happen.

Here is some code which demonstrates. Try and run that against my M thread test example to see how it should work. If you write any more code, try it against the test code to see if it works.

adante
Sep 18, 2003
off the topic but for lack of better place to put it:

anybody know of any good editors out there for groovy? Preferably with code complete/assist*, auto formatting, fix imports and the other shiny stuff that eclipse has. Too long with eclipse has made me soft and I cannot code without these functions anymore!

I have tried the eclipse plugin but it leaves a lot to be desired.

*Obviously this is much harder to do for groovy, but I'm not a details man.

Adbot
ADBOT LOVES YOU

adante
Sep 18, 2003
I want to... send a [method/closure/function/some computation sequence] that has been defined at runtime over the network :banjo: Is it possible in java?

For instance if I have some method wrapped in a class:

code:
public Class MethodWrap {
	static Object myMethod(Object arrr) { return "ARR!! " + arrr.toString(); }
}
the myMethod() call is not going to do anything fancy except do some computation, *maybe* access some java platform stuff (java.util.*), invoke methods on the arguments and so forth. The java versions on both sides will be identical.

is it possible for me to send this to another completely seperate java runtime which has no prior knowledge of the class?

I was thinking of trying to serialize the class (as in, the actual MethodWrap.class) into byte form, send it over network, unpack is and then somehow call ClassLoader#defineClass() to obtain a Class type, and use reflection to call the myMethod.

Problem is:
1. Don't know how to serialize MethodWrap.class. If I try something like Object o = MethodWrap.class and then serialize object o as I normally would, it creates a tiny byte[] array which obviously doesn't represent the full class.

2. Don't know how I would call defineClass() as it is a protected method. Are there other accessor/helper methods I should be using?

This is annoying hard to google as well. Anybody have any ideas?

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply