[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [equinox-dev] [prov] Strange error message: org.osgi.framework.BundleException: State change in progress for bundle ...

> 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 <Stefan.Liebig@xxxxxxxxxxxx>                                                                                      
                                                                                                                                              
  To:         equinox-dev@xxxxxxxxxxx                                                                                                         
                                                                                                                                              
  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
"initial@reference:
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
"initial@reference:
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@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/equinox-dev