Skip to main content

Cannot start JXTA Socket Server example in Websphere

18 replies [Last post]
desaipremal
Offline
Joined: 2008-07-03
Points: 0

When the JXTA Socket Server example code is instantiated in the WebphereServer, I get the following error message:

java.util.NoSuchElementException: key 'uuid' not registered.
at net.jxta.util.ClassFactory.getInstantiator(ClassFactory.java:362)
at net.jxta.id.IDFactory.newPeerID(IDFactory.java:857)
at net.jxta.platform.NetworkManager.(NetworkManager.java:156)

I do not understand why the Network manager is having a problem initializing when it does normally when the SocketServer class is run as a standalone program.

Not much information available in the error message or log.

Any help will be appreciated.
Premal

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
galato
Offline
Joined: 2007-07-06
Points: 0

Ok man I think I am getting a bigger picture of where your thoughts come from - I did find the Equinox thread you were posting and I read through it. So you built a (OSGi) bundle that loads the resources you need before the bundle that starts the NetworkManager - correct? First, aren't all of these bundles running in the same container and under a single JVM?

So my issue is similar - I need to load the config.properties before I make calls to the IDFactory to generate a new peer group id for me - and since what I have is an apk archive (similar to jar in standard java but this is in Android) with the net/jxta/impl/config.properties in it, I will need to load it first and have the jxta layer understand that I have it (by may be placing it in cache) to read it instead of trying to do it by itself.

What do you think?

keesp
Offline
Joined: 2007-05-22
Points: 0

In response to both of your posts...yes, I am proposing changes in te JXSE package itself in order to solve these problems, but the more help on different platforms we get, the better we can ensure that a future (next?) JXSE release will perform under various circumstances.

In Eclipse every plugin (basically a jar with some meta-information) is loaded in a different virtual machine and run autonomously, as Eclipse tries to create a very strict component based structure. I am no sure what happens VM-wise if one plugin uses another, but practically the issues of that we are discussing here is one of the main problems I run into in an Eclipse environment. I have been orking around this problem for two years now, and with the current boost of JXSE 2.6 activitities, I am hoping to contribute to making JXSE 2.6x better especially on these platform-specific problems.

I think that your situation is interesting because Android is going to be used more and more, and so JXSE should be equipped to deal with this. I don't know if you are building the JXSE from source files, but if you do you could try to make the change --it's a minor one--- in IDFactory and see f it solves your problem.

Cheers

Kees

galato
Offline
Joined: 2007-07-06
Points: 0

Although I was trying to keep the jxse baseline untouched, yes I am building off the source since Android requires recompilation to its bytecode. So it does make sense to make the change and test it against the issue I have and see how it does. Still in my case I think I may need to do more than changing the code in the IDFactory because Android separates the resources from the binary classes tree during packaging - that is, the config.properties is not in the net/jxta/impl of the jar but in a separate directory. But the concept of what you are referring to is the same.

I will let you know how it goes Kees and thanks for the help so far!

keesp
Offline
Joined: 2007-05-22
Points: 0

I understand. Do you know what the Android philosophy is for this design choice? It would seem to me that this implies that more JAVA code will have problems running on Android, because of this separation. Another interesting question is whether JXSE itself might separate the resources from the java code. I tend to think that current solution is quite elegant as it follows a good component-based modelling practices. I could imagine that a change in the jar structure (in a future release of JXSE) that would create a resources branch and a net.java branch ( a bit like the maven structure) might provide a 'best of both worlds' situation, but I don't know if this is sufficient to make JXSE 'Android compatible'

Cheers

Kees

galato
Offline
Joined: 2007-07-06
Points: 0

Hey Kees - no idea behind the design choice - I am new to that platform so I didn't question much about it yet ;)

Good questions - at least for Android, since it runs on constrained devices it made sense to have a 'resource' dir separate from the code and having an API to access them. In any case, let's see what others might say on this. For now I will give the code change a chance.

Thanks again

galato
Offline
Joined: 2007-07-06
Points: 0

Hi all -

was this ever resolved? Strangely enough I am seeing this error now when I import JXTA into Android. Anyone knows why this would be the case with the creation of the peergroupid?

Thanks

adamman71
Offline
Joined: 2007-01-31
Points: 0

Do we have logs or code examples to replicate the issue?

galato
Offline
Joined: 2007-07-06
Points: 0

Well in my case I am executing this code that works fine under Linux (or a laptop) on the Android emulator. So I am not sure it will be easy for you to replicate it. But for the guys who posted this originally I was wondering if they found a resolution - by looking at their resolution I was hoping I could get an insight as to how to deal with it on Android. So may be this is a dead end since they posted this issue a while back ...

The code just in case is this - I still think something may not be getting initialized correctly before this is called ... I will keep looking:

PeerGroupID peergroupid =
PeerToPeerAdapter.createInfrastructurePeerGroupID(System.currentTimeMillis()+"", "group");

---

public static final PeerGroupID createInfrastructurePeerGroupID(String clearTextID, String function){
byte[] digest = generateHash(clearTextID, function);
net.jxta.peergroup.PeerGroupID peerGroupID = IDFactory.newPeerGroupID( digest );
return peerGroupID;
}

---

public static final byte[] generateHash(String clearTextID, String function) {
String id;
if (function == null) {
id = clearTextID;
} else {
id = clearTextID + "-" + function;
}
byte[] buffer = id.getBytes();
MessageDigest algorithm = null;
try {
algorithm = MessageDigest.getInstance("MD5");
} catch (Exception e) {
return null;
}
algorithm.reset();
algorithm.update(buffer);

try{
byte[] digest1 = algorithm.digest();
return digest1;
}catch(Exception de){
return null;
}
}

keesp
Offline
Joined: 2007-05-22
Points: 0

I am not sure if this is the answer, but I think this may be related to the issues I am working for with my eclipse port. What happens (I think) that the jar files you work with are configured in such a way that the network manager is not able to read the config.properties file (which defines the String uuid). This file is part of the jar file and contains resource bundle properties. In eclipse this happens, for instance, when the JXSE code is available in a jar that runs in a separate virtual machine than the code that calls the network manager. It only happens initially when the network manager needs to create the advertisement cache. Once that is made (for instance by an older version of JXTA) you will not get the error.

Based on my experiences, I think that a likely candidate for the problem would be classpath settings or something similar. In a (websphere) server it may also be related to differences in the virtual machine.

Kees

Message was edited by: keesp

galato
Offline
Joined: 2007-07-06
Points: 0

Hey Kees - thanks for the response.

I am assuming you are referring to the config.properties file in the net..jxta.impl directory. May be that could be an issue but I do use the jxta.jar anyway in the standard implementation (non mobile) of my application and it works fine. Why would the jar be running on a different JVM? These are classes that the main application imports when it gets launched in the JVM - can you elaborate as to what you mean here?

In any case, I think you may do have a good pt regarding classpath settings even though I am using the same classpath settings as the ones I use with the standard app and which it does execute this code properly .. hmm ..

Thanks I will keep digging with your points in mind ...

keesp
Offline
Joined: 2007-05-22
Points: 0

I am getting more convinced that you are facing a variant of the problem of the config.properties file (you are indeed right), so I'll be a bit more specific as to what happens. The problem is that the resource bundle loader is looking for a config.properties file at "net.jxta.impl" (from my mind...something like that) which normally is quite correct. However, when the jar is not accessed in a straightforward way, which happens in the plugin structure of Eclipse, and I would think also in (some) web server configurations, the bundle loader no longer looks for the file in the place where it actually is.

In Eclipse, for instance, this happens because I have built a JXSE plugin (which runs in its own JVM because of the way Eclipse works) and I use the networkmanager in another plugin.So I have a net.jxse.26x plugin (basically the JXSE jar file) and a org.mycompany.myapplication plugin. When I start the network manager, it at some point calls the IDFactory which expects to find the config.properties file at org.mycompany.myapplication.net.jxta.impl, so starting to look from the root of the main application. Understandably it finds nothing there, because the config.properties file is located in net.jxse.26x.net.jxta.impl.
The same problem can happen, I think, when the jxse.jar is put in the lib directory of a web application, because there is a chance that the server will look for the config.properties file from the root location of the web application, and not from WEB-INF/lib or the place where the jxse.jar is located. I think that normally this problem does not occur, because the default classpath settings put all the used jars from a shared root.

I have implemented a workaround in Eclipse by starting the jxse plugin autonomously (this is possible in Eclipse), which does little more than load the resource bundle from a singleton, and performing a check if the resource bundle is already loaded. If this is first done (from the correct plugin), then the network manager who is called from other plugins will find the resource bundle already loaded in the Singleton and use that one, insterad of trying to load it itself. But I think this solution is very Eclipse specific, and I am looking for a better solution that may be taken up in the next release. note also that this problem also will occur with calls to the user.properties file which is also called at some point.

I am currently still looking whether another problem may ALSO occur, which is visibility of the config file, but if this is at all a problem, it will probably be specific for Eclipse, so I will not confuse you with this issue.

Hope this gives some directions for your own quest. Please keep me (us) posted so I can take up your findings in my own tests.

Cheers

Kees

galato
Offline
Joined: 2007-07-06
Points: 0

Hey Kees,

actually I am pretty familiar with what you are talking about - I know the IDFactory (which I am using to generate the peergroupid before I even call the NetworkManager/NetworkConfigurator) makes calls to the java.util>ResourceBundle which in turn expects a qualified basename (in our case net.jxta.impl.config) to look for. Eventually when the bundle is found the ID key (in this case uuid) gets registered in the AssocTable etc. And you are right, the ResourceBundle will chase the prop file in the cache first and if it does not find it tries to look from the root down to find it.

One interesting thing about the Android plugin under Eclipse is that it generates an archive file that separates the classes from the resources. So the resource config.properties is automatically inserted under root/net/jxta/impl - which is where the NetworkManager should be looking into. That's why I was a bit puzzled as to why it cannot find it. Regarding standard JXSE apps that I am running under Eclipse I never had to worry about all this - the classpath as you pointed out is set to point to the jxta.jar and when the app is launched the config properties is found inside the jar at runtime. I never had to "expose" it through a separate process or a plugin for the NetworkManager to find it.

In any case, your description below is very interesting and I appreciate it. I will certainly let you know how it goes and you have certainly gave me a good direction to check out.

Thanks again

keesp
Offline
Joined: 2007-05-22
Points: 0

No worries!

As I said earlier, I am currently trying to see what is necessary to make the JXSE 2.6x jar a full-fledged Eclipse (Equinox) plugin, and this problem seems to be the major stand-in-the-way. I am looking for a simple but effective means to address this, and hopefully the JXTA architects will implement this in an upcoming release. I think solving this issue will make the JXSE.jar much more versatile, as I don't think the problems I am running into are specific for Eclipse/Equinox, but basically covers a large number of class-path/classloading problems one runs into when using JXSE in non-standard environments.
(also see: http://forums.java.net/jive/thread.jspa?threadID=148915&tstart=0)

Currently my thoughts are that part of the problem MAY be resolved by changing the current loading of the propertybundles by using the getClass().getResourceAsStream method instead, as this is the preferred way of loading resources in Eclipse. however, I am still wondering if this will really make a difference, as I wonder if the current approach ResourceBundle.getResource() basically uses the same method. Theoretically, getResourceasStream uses the root of the jar as reference, and so this would always work. In the IDFactory the following construct would be used:

InputStream in = IDFactory.class.getResourcesAsStream("/net/jxta/impl/config.properties");
ResourceBundle jxtaRsc = new PropertiesResourceBundle( in );

If this approach is used everywhere where resources are used (config.properties and user.properties), then this problem should not occur. However, although I have successfully implemented this, I still feel that it will fail in some circumstances.

Another option might be that the IDFactory is called from an Executor thread, but I am unsure whether this guarantees that the thread is actually run in the same VM as the JXSE jar, or if the calling plugin starts a new thread, which would make the construction redundant.

Do you have any thoughts?

Thanks

Kees

galato
Offline
Joined: 2007-07-06
Points: 0

Hey Kees,

I will need to think about this a bit more before I can offer any more thoughts but
you are right, I think the PropertiesResourceBundle (that also some people on the Android mailing list are suggesting) should work but one should look into many more cases to make sure it is bullet proof. In any case, thanks for the good explanations and I will keep this thread alive with anything new I may have.

Cheers

galato
Offline
Joined: 2007-07-06
Points: 0

Hey Kees,

can you override the ResourceBundle of the IDFactory to impose a different path from your app? If I remember well the IDFactory uses the following right? Or you are proposing a change in the baseline?

private IDFactory() {
...
// Get our resource bundle
ResourceBundle jxtaRsrcs = ResourceBundle.getBundle("net.jxta.impl.config");
...
}

keesp
Offline
Joined: 2007-05-22
Points: 0

This is possible, but you would still create a moving target. The most important change would be that the resource bundle is always searched from the root of the jar in which the properties is found. As far as I know, the following ensures this (see previous post:):

InputStream in = null;
try{
in = this.getClass().getResourceAsStream("/net/jxta/impl/config.properties");
PropertyResourceBundle jxtaRsrcs = new PropertyResourceBundle( in );
...
}
finally{
in.close();
}
..but I am still wondering if the ResourceBundle.getBundle(..) is actually calling the getResourceAsStream method...in that case my fix would not be an improvement, of course ... :(

galato
Offline
Joined: 2007-07-06
Points: 0

Right I understand - I may have understood what you were saying wrong - were you
suggesting a change directly in the IDFactory class or a change at the application layer that can alter what the jxta baseline currently does? I think the former ....

By the way, the loadBundle method in ResourceBundle does call the getResourceAsStream but not the getBundle or the getBundleImpl.

Hey Kees thanks again for the good info man

jondtaylor
Offline
Joined: 2008-12-07
Points: 0

I have run into this problem as well when running my JXTA application from a Jar. It will run when not in a jar though.

I have tracked the problem to the JXTA class: net.jxta.id.IDFactory.java
public static PeerID newPeerID(PeerGroupID groupID)
...
Instantiator instantiator = factory.getInstantiator(useFormat);
// This method does not return and an exception is thrown.

factory is an instance of IDFactory, But I don't understand what is happening....