[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 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