I am creating a process in BPEL (say findRules) which has three Java Embeded Activity(A,B,C). and I have one java class(Rule.java) which I need to import on all Java Embed Activity.
and when I create an instance of Rule.java A activity, can I use the same instance in B and C activity.
because I am performing some business logic in A and wanted to access the updated varibles in B and C. but because B and C are having new instance I am not able to find those updated variables.
If you are Oracle SOA suite, there is a way to do this, albeit a very dirty one. The old WLI tags are still available. Note that this will remove portability of your code.
<jpd:javacode xmlns:jpd="http://www.bea.com/wli/jpd" >
public void f() {
LOGGER.log("Some log statement");
}
</jpd:javacode>
Then, you could use this Java method f(), and the same way as in wli (Using jpd:node and jpd:methodName tags)
Java Embedded Activities are not part of the BPEL standard, so without knowing which BPEL tooling you use it is impossible to give an appropriate answer. However, from a design point of view, I would guess that a middleware vendor would better isolate such activities. BPEL processes are typically meant to be executed in a long-running fashion and are able to survive hardware and software crashes. Making java objects visible to certain activities would IMO break these concepts.
Related
I'm working on a project in Java that will most likely support Android in the future. But from what I know, Android has different classes/APIs than default Java (for example, I don't think android has all of the AWT stuff). So what I'm wondering, is how can I write my code so that if it is running on Android, it will use the android APIs, and if it is on a desktop, it use the standard Java APIs. I have looked into conditional imports, but unlike C++, that doesn't exist in Java. So how is this kind of thing solved in Java.
Here is an example of what I would like to be able to do:
int[] i;
if(onAnroid)
{
i = androidFoo.bar();
} else {
i = javaFoo.bar();
}
EDIT:
One thing I had thought of was using a Common class so I don't directly call the APIs. But What I was trying to figure out is how to call those classes of they aren't necessarily existent without the compiler complaining that the classes don't exist.
You can create architectural layers which are agnostic of any particular user-interface toolkit. If these need to interact with the user interface, they can do so through interface types.
Atop those layers, you can create multiple presentation layers with different toolkits.
Porting software to new user interfaces is common. Separating architectural layers from the beginning can cost little. De-tangling a monolith later can be expensive, sometimes to the point that it is economically infeasible for a company. Whether a requirement to port is certain, possible or unknown, it can be a good practice to separate architectural layers early.
You will have to separate your code, but not like this. Your classes need to be designed to separate the code that is platform dependent from the code it isn't. You should focus on keep the core logic of the application in one layer and render the objects on the screen in another layer.
Regarding not-necessarily existing classes you can call like this:
try {
MyObject o = (MyObject)Class.forName("org.me.MyObject").newInstance();
} catch(ClassNotFoundException x) {
// Here you know class does not exist
}
Actually, you should do better than this but I don't remember. But anyway similar to this.
Dependency Injection can probably serve your needs. There are several Frameworks out there: http://en.wikipedia.org/wiki/Dependency_injection#Frameworks_that_support_dependency_injection
I got two Java web services, hosted in Tomcat on the same server.
Is there any way to share memory (objects) between them?
I can turn the sharing into some kind of web methods calls, however
this is complicated, a lot of changes are required.
this is not really sharing, objects are duplicated, although it should work for my case.
this will expose methods that should not be called by the clients.
Not that I know of. Sounds like it's fraught with peril. It's hard enough to synchronize objects in one app; you have no hope with two. What good could this possibly do?
If it's common methods you need, put them into a service that both can call. If it's common data, put it in a database.
Is there any way to share memory (objects) between them?
You can create a shared memory region that is shared by two JVMs. You can do this using native code, or (in theory) by mapping a file into the address-space of two apps.
But you can't put Java objects in that region. The JVM doesn't support this, either in Java code or in native code. (And even if you could, synchronization would be a big problem.)
So could you use shared memory to share data between two JVMs?
Maybe. But you'd need to treat the share memory segment as a kind of database, and implement a scheme for copying object state between the segment and each JVM's heap. And you'd need to implement a robust synchronization scheme, probably using semaphores.
In short, it would be a significant amount of work to implement, and it wouldn't "feel" like the JVMs were sharing objects. It would be easier to use an existing database or distributed caching solution.
Try using JCS:
http://commons.apache.org/proper/commons-jcs/
Hope it helps! ;)
On Inter process communications, Java says:
To facilitate communication between processes, most operating systems
support Inter Process Communication (IPC) resources, such as pipes and
sockets. IPC is used not just for communication between processes on
the same system, but processes on different systems.
I would rather go for pipes or sockets. This will make your life a lot easier and your web services more flexible, as they can run on two separate machines still with the ability to talk to each other as if they were setting side by side.
This is being said, back to practice. Say for example you have a set of objects {a,b,c} you want to share between your services. Create a data store class that holds {a,b,c} objects and whenever there is an update, do it in the data store dataStore.setA(A new_a). Behind the scene, and for every update, the local data store will notify the remote data store sitting in the other application and transmit all the updates that have just been made. The following DTO can be used to transmit all changes from one data store to another:
public class ObjectUpdateEvent<Source> implements Serializable {
private String fieldName;
private Object previousValue;
private Object newValue;
private Source source;
// Constructor...
}
Updating an the object "a" can be done the following way
public class DataStore{
// .....
public setA(A new_a){
ObjectUpdateEvent<DataStore> updateDto = new ObjectUpdateEvent<DataStore>();
updateDto.setPreviousValue(a);
updateDto.setNewValue(new_a);
sendUpdateDto();
a = new_a;
}
}
EDIT: This is exactly what #duffymo mentioned above.
How about using a shared library.
You can refactor your logic, move them to a separate library, and build as a separate jar.
The jar should be place in tomcat_home/lib directory.
And in your web apps the library dependency should be set as provided ( in maven )
You store create and store the objects you need to be shared in the shared memory, and access them from any web
I am fooling around with some basic programming in Android using Eclipse. I'm currently looking through a book and playing with some sample code that is written in the book.
I have noticed that in this particular book, all of the examples so far take pace in Main-Activity. I don't believe this to be very good Object Oriented programming practice as I am from a traditional Java background.
Is this the common practice for mobile platforms? Shouldn't classes all be contained in their own files?
Shouldn't classes all be contained in their own files?
Not necessarily as an Android Activity is a 'special case' class. If you haven't done already, I'd recommend you read Application Fundamentals and in particular the section on 'Activities' under Application components...
An activity represents a single screen with a user interface. For example, an email application might have one activity that shows a list of new emails, another activity to compose an email, and another activity for reading emails. Although the activities work together to form a cohesive user experience in the email application, each one is independent of the others. As such, a different application can start any one of these activities (if the email application allows it). For example, a camera application can start the activity in the email application that composes new mail, in order for the user to share a picture.
Note the section of text that I've highlighted in bold. The point is that an Activity in itself is not the complete app and if allowed, any third-party app can potentially invoke an Activity in one of your apps. As such, it is common to make an Activity as self-contained as possible. One particular example is the use of something like an AsyncTask which provides methods to execute a background thread as well as manipulate the UI - nesting a private class which extends AsyncTask is quite common and simplifies code. Nesting classes which extend BroadcastReceiver is also common for the same reason.
That said, there is nothing wrong with using separate Java class files for POJO helper classes, for example, it just comes down to how complex your app is but it can mean taking special consideration of how certain Android classes work - the AsyncTask class being one in particular if defined in a separate class file, try it and you'll see what I mean. :-)
OO is about putting functionality in classes. The way you write those classes defines if it is good OO or not (although this is debatable). Whether all these classes are in a single or a few files, or each class has its own file, is a matter of taste and is not directly an OO issue.
Since this is a book with (I think) small samples, it may be just as easy to read the way it is, than when all classes are in separate files.
If you use proper OOP you can create Template based apps much more quickly & efficiently.
You should strive to do this for example if you have a generic database app and multiple databases can be used with minor changes.
I'm writing a small application in RCP to wrap around the business logic in another (non-RCP) simulation library. I can access and use the library fine from any of my plugins, but I don't know where I should put the instance of the Simulation library so that, say, one of the command handlers can make calls to it.
From reading the docs it sounds like I should be storing 'global' information like this in the workbench - but I still don't really understand how to do that.
Help?
First, the business layer (BL) can and should reside in its' own plugin. That will provide decent decoupling between the layers.
Second, you should carefully decide what the interface should be and which classes are exposed. Ideally, you should mostly expose interfaces and data objects.
Finally, decide how the "hand shake" works. E.g., how to obtain the initial interface to the BL. Since it is a Plugin, it could have an Activator which loads it. You could add a method in the activator which returns the BL interface.
If you are looking for something more decoupled, you could create an extension point or deploy the BL as an OSGi service, but that's a bit of an overkill for you need.
If I understand you correctly, I see two ways:
Store the instance in the model plug-in itself, using ‘SimulationFactory.getInstance(String myAppId)‘. The passed String is a constant in you app that is always used, when obtaining the reference.
Define a new class e.g. GlobalAccess in you app that is initilized with an instance of your model and has some getter (whether you use a single instance again or only provide public static methods is a matter of taste).
The seocond way is similar to some classes in eclipse like platfom or platformui, where you can obtain initial references and navigate through the workbench.
edit
i just found a tutorial that might help you:
Passing Data between Plug-ins
My problem is that I'm working on a project that requires me to run multiple instances of someone elses code which has many static attributes/variables, which causes all the instances to share those resources and, well, crash. I can run multiple instances of this other person's program if I create a .jar file off of it and open it multiple times by running the .jar in windows, but running calling the "main" method multiple times in my code (which is what I need to do) won't work.
I thought about creating a .jar and using Runtime.getRuntime().exec( "myprog.jar" ); to call the program multiple times, but that won't work for me since I have to pass an instance of my object to this new program and I don't think this solution would allow for that.
PS: This is also posted in the Sun forums, so I`ll post the answer I get there here or the answer I get here there naturally giving proper credit once I this is solved =P.
Remember that a static element in Java is unique only in the context of a classloader (hierarchy); a class is uniquely identified in a JVM by the tuple {classloader, classname}.
You need to instantiate isolated classloaders and load the jar using that class loader. Each loaded class (and thus statis elements) are unique in their classloader and will not interfere with one another.
I'd say you have three alternatives:
Refactor the legacy application so that it doesn't use static attributes. If you can do this, this may be the best solution in the long term.
Continue with your approach of launching the legacy application in a separate JVM. There are a number of ways that you can pass (copies of) objects to another JVM. For example, you could serialize them and pass them via the child processes input stream. Or you could stringify them and pass them as arguments. In either case, you'll need to create your own 'main' class/method that deals with the object passing before calling the legacy app.
I think you should be able to use classloader magic to dynamically load a fresh copy of the legacy application each time you run it. If you create a new classloader each time, you should get a fresh copy of the legacy application classes with a separate set of statics. But, you have to make sure that the legacy app is not on your main classpath. The problem with this approach is that it is expensive, and you are likely to create memory leaks.
The description is a little confusing.
If you are running the code multiple times, you are running multiple independent processes, each running in its own JVM. There is no way that they are actually sharing the values of their static fields. Java doesn't let you directly share memory between multiple VMs.
Can you elaborate more (ideally with examples and code) what the attributes are defined as and what kind of failures you are getting? This may be completely unrelated to them being static.
In particular, what exactly do you mean by shared resources? What resources are your programs sharing?
The proper approach was already suggested - using custom ClassLoaders. Another thing comes to my mind, which might seem ugly, but will probably do, and is a bit more object-oriented approach.
The legacy code is used for its operations, and it incorrectly uses static instead of instance variables. You can fix that using inheritance and reflection:
create (or reuse) an utility class that copies instance variables to static ones
extend the classes in question and provide the same instance variables as the static ones
override all methods. In the overriding methods use the utility to copy the state of the current object to the static variables, and then delegate to (call) the super methods.
Then start using instance of your class, instead of the legacy ones. That way you will simulate the proper behaviour.
Have in mind this is NOT thread-safe.