Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [ecf-dev] Problem regarding hello.ds examples.

 Hi Jeff,

On 9/16/2010 11:48 AM, Jeff Hamm wrote:
<stuff deleted>

In regards to a broadcast mechanism, the system that I am designing is a typical 3-tier system where the customer will interact with a web interface to a jetty http server in an administrator type of role making requests out to 1 or more client machines where the remote services are hosted. The http server needs to be able to make synchronous and async calls to the services hosted on a single machine or to several machines at once in a broadcast fashion.

It's this last case that is the most interesting and problematic for the OSGI remote services model. All the others are naturally supported by ECF remote services (OSGI remote services has everything but asynchronous support, and that is also supported by ECF's remote services impl).

By 'making calls to several machines at once in broadcast fashion'...what exactly do you mean/expect occur with the *results* of the remote call? That is, if I invoke a method on 3 pub/sub group members, and all three return an Integer, what result(s) do you expect on the service consumer? This is the part of the pub/sub model that is not a direct fit to 'normal' OSGi remote services (which is basically remote method call)...as the assumption in the OSGi service model (java method call) is that there is but one return value.


Likewise, the clients will need to be able to respond back to the server with the synch and async events autonomously creating a byway set of communication bridges for lack of a better term.

This is sounding more like a message bus...where the assumption is that messages are sent to n receivers...all of which are in the same pub/sub 'group' (in jms it's referred to as a 'topic', in JavaGroups it's a 'group'). The assumption with this model is that all messaging is asynchronous (no blocking/waiting for return values...at least partially since there could be n return values), all group participants can be both senders and receivers (at least conceptually).

OSGi has direct support for the 'group' model via the EventAdmin service, which has the notion of asynchronously 'posting' a message to a given topic. Of course these messages to EventHandlers can easily result in local method call...and messages sent in reply.

ECF has a distributed EventAdmin implementation [1] which uses supporting providers to do the underlying inter-process messaging via JMS, ECF generic, JavaGroups, XMPP chat room providers...and other providers that support the notion of a group/topic of receivers. ECF also has API (independent of provider) support for multipoint asynchronous message delivery via datashare channels (Datashare API), and shared objects (replicated object instances). For example, the distributed EventAdmin implementation uses the shared object API to implement the pub/sub inter-process messaging to support the asynchronous Event distribution between runtimes.

Note that r-OSGi provider, being based upon a client-server model (with http for comm), does not have support for the notion of a group/topic with multiple receivers.

Does this make sense? Let me know if there are more questions...although I may not be able to provide full support given my own time constraints.

Thanks,

Scott

[1] http://wiki.eclipse.org/Distributed_EventAdmin_Service



Where I am at (programmatically) now is plugging in the remote services in between the services that the http server used to provide so that those services can be made available across the set of clients. I am hoping that once I get the *plumbing* squared away and am able to design the api's in the form of the remote proxy's that switching out the r-osgi, or adding other mechanisms to it will be easy to accomplish. So for right now having a point to point connection is good, but not the end goal.

Any information that you can provide is definitely welcome!

Thanks again --
Jeff

-----Original Message-----
From: ecf-dev-bounces@xxxxxxxxxxx [mailto:ecf-dev-bounces@xxxxxxxxxxx] On Behalf Of Scott Lewis
Sent: Thursday, September 16, 2010 2:24 PM
To: ecf-dev@xxxxxxxxxxx
Subject: Re: [ecf-dev] Problem regarding hello.ds examples.

   Hi Jeff,

On 9/16/2010 8:06 AM, Jeff Hamm wrote:
Just to update everyone and seek further clarifications....

Thanks again to everyone who has responded.

I was unable to get the hello.ds stuff fully integrated into my project so for the meantime I fell back to the r-osgi example and now have a functioning system. :)  I will need to migrate to some type of broadcast mechanism (XMPP??) to talk to multiple client machines but for now I'm happy that something is working and I can proceed.
WRT 'broadcast mechanism'...to point you at specific technologies within ECF I would need to understand the needs/use case here...e.g.
distribution to pub/sub group (group multicast)?  asynchronous delivery?  Reliable multipoint delivery?  ECF has a number of relevant technologies/APIs here...including the ECF generic provider, XMPP provider, JMS provider, JavaGroups provider, the datashare API (channels for asynchronous message delivery), the shared object API, OSGi's Distributed event admin service [1], etc.

So my next issue has been how to extend the hello.rs example for more complex message types. I have been able to pass simple String messages back and forth as in the example but now I want to be able to use my own defined classes as message objects.

My hope was to do something like this.

In my service.api bundle, I have this class in the service.api.impl package.

public class Hello implements IHello {

	/**
	 * @since 2.0
	 */
	public String hello(HelloMessage from) {
		System.out.println("received hello from = "+ from.getMessage());
		return "Server says 'Hi' back to "+from;
	}

}

The class HelloMessage.java is in the service.api.impl package as well and looks like this:

import java.io.Serializable;

public class HelloMessage implements Serializable {

	static final long serialVersionUID = 8600267052211608861L;
	
	private String message;
	
	public void setMessage(String message) {
		this.message = message;
	}
	
	public String getMessage() {
		return this.message;
	}
}


  From here, there is the service.host.impl.RuntimeService.java in the service.host bundle that registers the service just as the example.

	helloRegistration = containerAdapter.registerRemoteService(
		new String[] { IHello.class.getName() }, new Hello(), null);


Now, in different bundle, the service.client bundle, I have the service.client.ServiceClient.java class that does the proxy lookup and calls the method. Again, similiar as the example.
public void callHello() {

......

	IHello proxy = (IHello) remoteService.getProxy();
	HelloMessage m = new HelloMessage();
	m.setMessage("This is a message from the object HelloMessage");
	String message = proxy.hello(m);
	System.out.println("received back from host '" + message + "'");

......
}

The problem I am seeing is that when I start the .product files for the server and then the client, I get the following exception:

java.lang.LinkageError: loader constraint violation: loader (instance of org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader) previously initiated loading for a different type with name "service/api/impl/HelloMessage"
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(Unknown Source)
	at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.defineClass(DefaultClassLoader.java:188)
	at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.defineClass(ClasspathManager.java:580)
	at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findClassImpl(ClasspathManager.java:550)
	at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClassImpl(ClasspathManager.java:481)
	at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass_LockClassLoader(ClasspathManager.java:469)
	at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:449)
	at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:216)
	at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:393)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:469)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:422)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:410)
	at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at java.lang.ClassLoader.loadClassInternal(Unknown Source)
	at java.lang.Class.getDeclaredMethods0(Native Method)
	at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
	at java.lang.Class.privateGetPublicMethods(Unknown Source)
	at java.lang.Class.getMethods(Unknown Source)
	at org.eclipse.ecf.internal.provider.r_osgi.RemoteServiceImpl.getMethod(RemoteServiceImpl.java:187)
	at org.eclipse.ecf.internal.provider.r_osgi.RemoteServiceImpl$4.run(RemoteServiceImpl.java:113)
	at org.eclipse.equinox.concurrent.future.SingleOperationFuture$1.run(SingleOperationFuture.java:96)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.equinox.concurrent.future.SingleOperationFuture.runWithProgress(SingleOperationFuture.java:89)
	at org.eclipse.equinox.concurrent.future.ThreadsExecutor$1.run(ThreadsExecutor.java:49)
	at java.lang.Thread.run(Unknown Source)


Note that I start each of the .product files within the same running instance of eclipse 3.6.
Ok...so first...I've added a HelloMessage class and a new/additional method to the IHello/IHelloAsync service interfaces and tested it out, and I do *not* get this exception (i.e. everything works ok with the serializable HelloMessage class...both for the r-OSGi and ecf generic distribution providers).  I will release this new hello example method/HelloMessage class to CVS repo soon (I need to do some basic clean up/simplification before doing so...but it will be in ECF 3.4).

Jeff what I suspect for your error is that you've got ECF (with r-osgi) installed in Eclipse...which means that R-OSGi starts itself up on 9278 within *Eclipse* (within the tooling)...and that when you run the service host/server on localhost you may get something like this in the system err (at the beginning when the new process starts up):

WARNING: Port 9278 already in use. This instance of R-OSGi is running on port 9279

This should *not* happen on the host...because if it does it means the consumer will access the R-OSGi instance on 9278...and that instance doesn't have the right class.  I think this may be the problem with your local system.

So in order to run a new r-osgi server/service host on localhost you need to disable r-OSGi within Eclipse, so that the server/service host you start can expose its service on 9278 (which is where the consumer is
looking).  See this page for information on doing this [1].    This is
currently endemic to the r-OSGi provider, because it always tries to run the service host on 9278...and running two servers/service hosts on a single system (localhost) creates problems for consumers.

There is one other issue that I want to warn you about...that's because of Eclipse launch configurations creating problems for the r-OSGi provider.  When you launch a product (e.g. from the product configuration editor Overview tab), it creates a launch configuration for that product.  Problem is, if you use this launch configuration, it can create problems for the r-OSGi provider, because it creates a new bundle dynamically (to hold the proxies)...and this proxy bundle can be
*stale*...if, for example, you've changed the IHello interface.   If you
see an NPE when starting a product that uses the r-OSGi provider then this is probably the problem.  The solution is simply to delete the launch configuration and then start the product from the product configuration editor Overview page.  Then the proxy bundle will be regenerated by r-OSGi when it starts up.

Thanks,

Scott

[1] http://wiki.eclipse.org/Disabling_R-OSGi

I searched this on Google and found that others have seen this and that it sometimes points to the class being referenced twice in one instance but I don't see that in my startup script unless something is pulling it in behind the scenes. Also, as above, the HelloMessage class is serialized.

Any thoughts? Thanks in advance!

Jeff



-----Original Message-----
From: ecf-dev-bounces@xxxxxxxxxxx [mailto:ecf-dev-bounces@xxxxxxxxxxx]
On Behalf Of Markus Alexander Kuppe
Sent: Friday, September 10, 2010 1:05 PM
To: Eclipse Communication Framework (ECF) developer mailing list.
Subject: Re: [ecf-dev] Problem regarding hello.ds examples.

On 09/09/2010 04:02 PM, Jeff Hamm wrote:
Hi again Markus,

I guess the thing that is confusing me the most is that I can run the example hello.ds and get the IHello service registered when launching as an application. However, when launching through my product launcher that uses the autostarter to load the bundles the service is never registered.
You might want to compare the Equinox/OSGi "ss" console output of both launches and post the output for your launch.

Markus
_______________________________________________
ecf-dev mailing list
ecf-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/ecf-dev

_______________________________________________
ecf-dev mailing list
ecf-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/ecf-dev
_______________________________________________
ecf-dev mailing list
ecf-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/ecf-dev

_______________________________________________
ecf-dev mailing list
ecf-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/ecf-dev



Back to the top