> It seems that there is a difference between loading a class (from another bundle) from the ´main´ thread and from a spawned thread while activating a bundle. There is no difference between loading a class from the main thread or from another thread. All calls end up in the same place. What you are experiencing here is a deadlock while loading classes, however because equinox is so cool, it is telling you so with the following message: "To avoid deadlock, thread "Thread[Thread-2,6,main]" is proceeding but "org.eclipse.equinox.internal.p2.artifact.repository.ECFTransport$1" may not be fully initialized."
This happens because while the bundle is being activated (and has not finished its activation, the call from Activator.start() has not returned), another thread is trying to load a class from it. However since the contract of our classloaders is to "fully activate the bundle" this class loading request can not be done. This kind of problem is usually encountered when activators are doing too much work. A good practice for activators is to do as little as possible. Now for this particular problem with the artifact repository manager, the problem stems from the eager loading of the repository content. Instead, on restart the repository manager should only load the URLs of the repository and then only load the content on request. This approach has already been implemented in the metadata repo manager but has not been put to use for the artifact repo manager. It may worth experiencing with this. HTH PaScaL From: Stefan Liebig <[EMAIL PROTECTED]> To: equinox-dev@eclipse.org Date: 12/17/2007 03:26 AM Subject: [equinox-dev] [prov] Strange error message: org.osgi.framework.BundleException: State change in progress for bundle ... I started to refactor SimpleArtifactRepositoryFactory to use ECFTransport instead of using URL.openStream() to load the artifacts.xml. In my first attempt I was using ECFTransport to download artifact.xml into a temporary file and than reading its content with SimpleArtifactRepositoryIO. This worked very well (I used ProvAdminUI for testing) but I didn´t like the temporary file storage. My second attempt was to use a PipedInput/Ouputstream pair to do that. Therfore I start a download thread which uses ECFTransport pushing into the PipedOutputStream and the linked PipedInputStream is read by SimpleArtifactRepositoryIO. When I now start ProvAdminUI I got the following error message: !ENTRY org.eclipse.osgi 2 0 2007-12-17 08:32:25.687 !MESSAGE While loading class "org.eclipse.equinox.internal.p2.artifact.repository.ECFTransport$1", thread "Thread[Thread-2,6,main]" timed out waiting (5000ms) for thread "Thread[main,6,main]" to finish starting bundle "[EMAIL PROTECTED]: file:../../projekte/rcp/org.eclipse.equinox.p2.artifact.repository/ [17]". To avoid deadlock, thread "Thread[Thread-2,6,main]" is proceeding but "org.eclipse.equinox.internal.p2.artifact.repository.ECFTransport$1" may not be fully initialized. !STACK 0 org.osgi.framework.BundleException: State change in progress for bundle "[EMAIL PROTECTED]: file:../../projekte/rcp/org.eclipse.equinox.p2.artifact.repository/" by thread "main". at org.eclipse.osgi.framework.internal.core.AbstractBundle.beginStateChange(AbstractBundle.java:1139) at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:259) at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:400) at org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:111) at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:419) at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:189) at org.eclipse.osgi.framework.internal.core.BundleLoader.findLocalClass(BundleLoader.java:344) at org.eclipse.osgi.framework.internal.core.BundleLoader.findClassInternal(BundleLoader.java:412) at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:373) at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:361) at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:83) at java.lang.ClassLoader.loadClass(ClassLoader.java:235) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:302) at org.eclipse.equinox.internal.p2.artifact.repository.ECFTransport.transfer(ECFTransport.java:72) at org.eclipse.equinox.internal.p2.artifact.repository.ECFTransport.download(ECFTransport.java:67) at org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactRepositoryFactory$Transporter.run(SimpleArtifactRepositoryFactory.java:68) Caused by: org.eclipse.osgi.framework.internal.core.AbstractBundle$BundleStatusException ... 16 more Root exception: org.eclipse.osgi.framework.internal.core.AbstractBundle$BundleStatusException at org.eclipse.osgi.framework.internal.core.AbstractBundle.beginStateChange(AbstractBundle.java:1139) at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:259) at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:400) at org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:111) at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:419) at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:189) at org.eclipse.osgi.framework.internal.core.BundleLoader.findLocalClass(BundleLoader.java:344) at org.eclipse.osgi.framework.internal.core.BundleLoader.findClassInternal(BundleLoader.java:412) at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:373) at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:361) at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:83) at java.lang.ClassLoader.loadClass(ClassLoader.java:235) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:302) at org.eclipse.equinox.internal.p2.artifact.repository.ECFTransport.transfer(ECFTransport.java:72) at org.eclipse.equinox.internal.p2.artifact.repository.ECFTransport.download(ECFTransport.java:67) at org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactRepositoryFactory$Transporter.run(SimpleArtifactRepositoryFactory.java:68) It seems that is not possible to load the ECF class IFileTransferListener within a thread (this happens at ECFTransport.java:72). The Activator of o.e.e.p2.artifact.repository creates the ArtifactRepositoryManager which does a restoreRepositories() in its constructor. This causes an attempt to create a SimpleArtifactRepository which than fails with the above error. When I delay the restoreRepositories() until it is really needed than the error does no longer occur. It seems that there is a difference between loading a class (from another bundle) from the ´main´ thread and from a spawned thread while activating a bundle. What is the difference? Stefan _______________________________________________ equinox-dev mailing list equinox-dev@eclipse.org https://dev.eclipse.org/mailman/listinfo/equinox-dev _______________________________________________ equinox-dev mailing list equinox-dev@eclipse.org https://dev.eclipse.org/mailman/listinfo/equinox-dev