Call java method with dbus - java

How is it possible to export a java method or object using dbus?
I am writing this because the official documentation is very poor and it took me hours to figure out how to do it.
Ideally the DBus interface should go in a java package

DBus.java
import org.freedesktop.dbus.DBusInterface;
import org.freedesktop.dbus.DBusInterfaceName;
#DBusInterfaceName("org.printer")
public interface DBus extends DBusInterface {
//Methods to export
public void Print(String message);
}
Main.java
import org.freedesktop.dbus.DBusConnection;
import org.freedesktop.dbus.exceptions.DBusException;
public class Main {
public static void main(String[] args) {
Printer p = new Printer();
try {
DBusConnection conn = DBusConnection.getConnection(DBusConnection.SESSION);
//Creates a bus name, it must contain some dots.
conn.requestBusName("org.printer");
//Exports the printer object
conn.exportObject("/org/printer/MessagePrinter", p);
} catch (DBusException DBe) {
DBe.printStackTrace();
conn.disconnect();
return;
}
}
}
//Printer object, implements the dbus interface and gets
//called when the methods are invoked.
class Printer implements DBus {
public boolean isRemote() {
return false;
}
public void Print(String message) {
System.out.println(message);
}
}
You can try this out with qdbus from the shell, running:
qdbus org.printer /org/printer/MessagePrinter org.printer.Print test

Related

Use Soot to analyze a Java program

I am trying to use Soot to perform data flow analysis on a java file which is called Example.java.
Here is my Example.java file, my goal is to know which saySomething method animal.saySomething() will call. Here is the code for Example.java I am using:
package a1;
public class Example {
static Animal neverCalled() {
return new Fish();
}
static Animal selectAnimal() {
return new Cat();
}
public static void main(String[] args) {
Animal animal = selectAnimal();
animal.saySomething();
}
}
abstract class Animal {
public abstract void saySomething();
}
class Cat extends Animal {
public void saySomething() {
System.out.println("purr");
}
}
class Dog extends Animal {
public void saySomething() {
System.out.println("woof");
}
}
class Fish extends Animal {
public void saySomething() {
System.out.println("...");
}
}
class Car { // not an Animal
public void saySomething() {
System.out.println("honk!");
}
}
and here is the code I am using to analyze Example.java using Soot, this code is located in the file: TestSootCallGraph.java which follows here:
package a1;
import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import soot.*;
import soot.jimple.Stmt;
import soot.jimple.spark.SparkTransformer;
import soot.jimple.toolkits.callgraph.CHATransformer;
import soot.jimple.toolkits.callgraph.CallGraph;
import soot.jimple.toolkits.callgraph.Targets;
import soot.options.Options;
public class TestSootCallGraph extends SceneTransformer {
static LinkedList<String> excludeList;
public static void main(String[] args) {
String mainclass = "Example";
// //set classpath
String javapath = System.getProperty("java.class.path");
String jredir = System.getProperty("java.home")+"/lib/rt.jar";
String path = javapath+File.pathSeparator+jredir;
Scene.v().setSootClassPath(path);
//add an intra-procedural analysis phase to Soot
TestSootCallGraph analysis = new TestSootCallGraph();
PackManager.v().getPack("wjtp").add(new Transform("wjtp.TestSootCallGraph", analysis));
excludeJDKLibrary();
//whole program analysis
Options.v().set_whole_program(true);
//load and set main class
Options.v().set_app(true);
SootClass appclass = Scene.v().loadClassAndSupport(mainclass);
System.out.println(appclass);
Scene.v().setMainClass(appclass);
Scene.v().loadNecessaryClasses();
//enable call graph
//enableCHACallGraph();
//enableSparkCallGraph();
//start working
PackManager.v().runPacks();
}
private static void excludeJDKLibrary()
{
//exclude jdk classes
Options.v().set_exclude(excludeList());
//this option must be disabled for a sound call graph
Options.v().set_no_bodies_for_excluded(true);
Options.v().set_allow_phantom_refs(true);
}
private static void enableSparkCallGraph() {
//Enable Spark
HashMap<String,String> opt = new HashMap<String,String>();
//opt.put("propagator","worklist");
//opt.put("simple-edges-bidirectional","false");
opt.put("on-fly-cg","true");
//opt.put("set-impl","double");
//opt.put("double-set-old","hybrid");
//opt.put("double-set-new","hybrid");
//opt.put("pre_jimplify", "true");
SparkTransformer.v().transform("",opt);
PhaseOptions.v().setPhaseOption("cg.spark", "enabled:true");
}
private static void enableCHACallGraph() {
CHATransformer.v().transform();
}
private static LinkedList<String> excludeList()
{
if(excludeList==null)
{
excludeList = new LinkedList<String> ();
excludeList.add("java.");
excludeList.add("javax.");
excludeList.add("sun.");
excludeList.add("sunw.");
excludeList.add("com.sun.");
excludeList.add("com.ibm.");
excludeList.add("com.apple.");
excludeList.add("apple.awt.");
}
return excludeList;
}
#Override
protected void internalTransform(String phaseName,
Map options) {
int numOfEdges =0;
CallGraph callGraph = Scene.v().getCallGraph();
for(SootClass sc : Scene.v().getApplicationClasses()){
for(SootMethod m : sc.getMethods()){
Iterator<MethodOrMethodContext> targets = new Targets(
callGraph.edgesOutOf(m));
while (targets.hasNext()) {
numOfEdges++;
SootMethod tgt = (SootMethod) targets.next();
System.out.println(m + " may call " + tgt);
}
}
}
System.err.println("Total Edges:" + numOfEdges);
}
}
I receive the following error when executing TestSootCallGraph.java which aims at analyzing Example.java. How can I fix this?
Example
Exception in thread "main" java.lang.RuntimeException: Main-class has no main method!
at soot.Scene.setMainClass(Scene.java:171)
at a1.TestSootCallGraph.main(TestSootCallGraph.java:47)

I have java.net.MalformedURLException

package RMI_Package;
import java.rmi.server.*;
import java.rmi.*;
public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote {
public String sayHello(){
return "Server says,'Hey'";
}
public MyRemoteImpl() throws RemoteException{}
public static void main(String [] args){
try{
MyRemote service = new MyRemoteImpl();
Naming.rebind("Remote Hello",service);
}catch(Exception ex){
ex.printStackTrace();
}
}
}
This code is from Head First Java Book when i run it, it throws the java.net.MalformedURLException.
As specified by the Naming documentation, the first parameter of bind should be a valid URL.
As an example (taken from here):
Naming.bind("rmi://localhost:8800/YourObject", service);

Transmitting an object's data (specifically, server variables) over RMI

Edit: The Java™ Tutorials say that
the server and the client communicate and pass information back and
forth
and that RMI
provides mechanisms for loading an object's class definitions as well
as for transmitting an object's data.
I was hoping that "an object's data" would include a server object's variables (such as Test.value in my code, below) - but the first comments I got indicate that perhaps I was wrong. My original question follows.
I am trying to access a remote object that I am sending over RMI to a client. I am only able to access its methods, but not its instance variables - I get the interface's fields instead. My question is, once I implement and instantiate a class on a server, how do I access its [public] fields, without using getters? I am able to send a stub without any errors or exceptions, but like I said, I am not able to access the server's object's fields, only the interface's. Following is an abbreviated version of my interface, implementation, server, and client.
package test;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface TESTint extends Remote {
double value = -22;
String shortName = "TESTint";
double getValue() throws RemoteException;
}
package test;
import java.rmi.RemoteException;
public class Test implements TESTint {
public double value = -33;
public String shortName = "TestAccount";
public int whole = 1;
public Test(String shortName) {
this.shortName = shortName;
print(shortName);
}
public double getValue() throws RemoteException {
return value;
}
public void print(Object o) {
System.out.println(shortName + ": " + o);
}
}
package test;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class RemoteTestMain {
Test test;
public static void main(String[] args) throws InterruptedException {
if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); }
new RemoteTestMain();
} // main
public RemoteTestMain() {
test = new Test("Charlie");
Registry registry;
try {
registry = LocateRegistry.createRegistry(1234);
registry.list( ); // will throw an exception if the registry does not already exist
print(test.shortName); // it gets it right here
print(test.value); // it gets it right here
TESTint r = (TESTint) UnicastRemoteObject.exportObject(test, 0);
registry.rebind("DCregistry", r);
print("test bound");
} catch (java.rmi.RemoteException ex) {
print("Remote Exception at Server");
ex.printStackTrace();;
}
}
public static void print(Object o) {
System.out.println("Server: " + o);
}
}
package test;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
TESTint test;
public static void main(String[] args) {
try {
new Client();
} catch (RemoteException e) {
e.printStackTrace();
}
} // main
private void init(int account) {
print("INITiating Account " + account);
try {
Registry registry = LocateRegistry.getRegistry(1234);
test = (TESTint) registry.lookup("DCregistry");
} catch (Exception e) {
System.err.println("RMI exception:");
e.printStackTrace();
}
print("Short name : " + test.shortName);
print("value: " + test.value);
try {
print("Value through getter is " + test.getValue());
} catch (RemoteException e) {
print("Could not get equity");
e.printStackTrace();
}
} // init(int account)
public Client() throws RemoteException {
if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); }
init(2);
}
private static void print(Object o) {
System.out.println("GUI: " + o);
}
}
P.S. In the Client code above, test.shortName is wiggly-underlined and Eclipse suggests that The static field TESTint.shortName should be accessed in a static way. I understand that the Client does not recognize the implementation, only the interface - but is there a way to access test's fields, not only its methods? I have many fields in my original code and I do not want to write getters for each and every one, if possible.
RMI stands for Remote Method Invocation which means that you can remotely execute a method of an object. The implementation of the method resides in the remote system. You can never access the instance variables of the implementation class which exists in the remote system even if they are public. You can only execute public methods which are exposed by the Inteface. So if you want to access the variables, you need add public gettter methods both in the Inteface and implementation class.

How is it possible to communicate between two classes in Java using an interface?

Hi ive been reading on some similar topics here but none of them answer my question. Some say you cant even do this which is not a good thing since I cant finnish my course in that case.
Heres som simple code. Think of each block as a separate class.
public interface Interface {
void printMessage(String meddelande);
}
public class Model implements Interface {
String message = "hej!";
public static void main(String[] args) {
Model model1 = new Model();
View view1 = new View();
model1.printMessage(model1.message); //Ska jag anropa funktionen såhär ens?
}
public void printMessage(String str) {
}
}
public class View implements Interface {
printMessage(String str) {
}
}
So, how is it now possible to tel the view to print this string from the model class without the classes knowing about each other? Its not allowed to send a reference of the model-objekt to the view-object. ; (
Define an Interface:
public interface MyInterface {
void printMessage(String str);
}
Define a class that can trigger the notification:
public class ClassNotifier {
MyInterface mInterface;
public ClassNotifier(MyInterface mInterface) {
this.mInterface = mInterface;
}
public void triggerTheMsg(String msg) {
if (mInterface != null) {
mInterface.printMessage(msg);
}
}
}
Define a class that will be informed:
public class InformedClass implements MyInterface {
public static void main(String[] args) throws Exception {
InformedClass c = new InformedClass();
ClassNotifier cn = new ClassNotifier(c);
}
#Override
public void printMessage(String newMsg) {
System.out.println("A new msg is here: " + newMsg);
}
}
How does it works?:
this is named a callback parttern, the class ClassNotifier has a reference to the interface MyInterface, which is impl. by Informed class to, so every time the ClassNotifier calls the method printMessage, the method printMessage in the class Informed will be triggered too.
I advice you to use dependency injection, for example:
public class Model {
String message = "hej!";
Interface printer;
public void Model(Interface printer) {
printer = printer;
}
public static void main(String[] args) {
Model model1 = new Model(new View());
model1.printMessage(model1.message);
}
public void printMessage(String str) {
printer.printMessage(str);
}
}

Simple App Won't Compile in Eclipse (with plugin)?

my code, being practically identical to the code given in BlackBerry's tutorial, has a syntax error in Eclipse. i'm sure there is some small but i'm just not seeing, but my coworker could not find it as well. any ideas would be greatly appreciated. thanks!
Code:
pushScreen(new ABCScreen());
Error:
Cannot make a static reference to the
non-static method pushScreen(Screen)
from the type UiApplication
here is the complete source:
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;
public class AwesomeBBCalculator extends UiApplication {
public AwesomeBBCalculator() {
AwesomeBBCalculator app = new AwesomeBBCalculator();
app.enterEventDispatcher();
}
public static void main(String[] args) {
pushScreen(new ABCScreen()); // ERROR LINE
}
}
final class ABCScreen extends MainScreen {
public ABCScreen() {
super();
// add title
LabelField title = new LabelField("Awesome BlackBerry Calculator",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
setTitle(title);
}
public boolean onClose() {
Dialog.alert("Thanks for using the Awesome BlackBerry Calculator!\nGoodbye.");
System.exit(0);
return true;
}
}
The pushScreen method can only be called within an instance of UiApplication. You are trying to call it from a static main method. That does not work. Do this instead...
public void foo()
{
pushScreen(this);
}
public static void main(String[] args)
{
(new ABCScreen()).foo();
}
public void class1()
{
pushScreen(this);
}
public static void main(String[] args)
{
(new NewScreen()).class1();
}
try making an object for the ABCScreen class and then use it or u may try this also:
UiApplication.getUiApplication().pushScreen(new ABCScreen());

Categories