Bug 559165 - deadlock triggered by classloading triggered by
TransformerPlugin.acquireLog()
diff --git a/features/org.eclipse.objectteams.otequinox.feature/feature.xml b/features/org.eclipse.objectteams.otequinox.feature/feature.xml
index 139f628..cbad16d 100644
--- a/features/org.eclipse.objectteams.otequinox.feature/feature.xml
+++ b/features/org.eclipse.objectteams.otequinox.feature/feature.xml
@@ -2,7 +2,7 @@
<feature
id="org.eclipse.objectteams.otequinox"
label="%featureName"
- version="2.7.6.qualifier"
+ version="2.7.7.qualifier"
provider-name="%providerName"
plugin="org.eclipse.objectteams.otequinox"
colocation-affinity="org.eclipse.rcp">
diff --git a/plugins/org.eclipse.objectteams.otequinox/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.otequinox/META-INF/MANIFEST.MF
index 5335561..c470289 100644
--- a/plugins/org.eclipse.objectteams.otequinox/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.objectteams.otequinox/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.objectteams.otequinox;singleton:=true
Automatic-Module-Name: org.eclipse.objectteams.otequinox
-Bundle-Version: 2.7.6.qualifier
+Bundle-Version: 2.7.7.qualifier
Bundle-Activator: org.eclipse.objectteams.otequinox.TransformerPlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin
diff --git a/plugins/org.eclipse.objectteams.otequinox/META-INF/p2.inf b/plugins/org.eclipse.objectteams.otequinox/META-INF/p2.inf
index 4abb4df..8f90ced 100644
--- a/plugins/org.eclipse.objectteams.otequinox/META-INF/p2.inf
+++ b/plugins/org.eclipse.objectteams.otequinox/META-INF/p2.inf
@@ -4,11 +4,11 @@
units.0.id = org.eclipse.objectteams.otequinox.configuration
-units.0.version = 2.7.6.$qualifier$
+units.0.version = 2.7.7.$qualifier$
units.0.hostRequirements.0.namespace=osgi.bundle
units.0.hostRequirements.0.name=org.eclipse.objectteams.otequinox
-units.0.hostRequirements.0.range=[2.7.6,3.0.0)
+units.0.hostRequirements.0.range=[2.7.7,3.0.0)
units.0.hostRequirements.1.namespace = org.eclipse.equinox.p2.eclipse.type
units.0.hostRequirements.1.name = bundle
units.0.hostRequirements.1.range = [1.0.0,2.0.0)
@@ -17,7 +17,7 @@
units.0.properties.0.value = true
units.0.requires.0.namespace = osgi.bundle
units.0.requires.0.name = org.eclipse.objectteams.otequinox
-units.0.requires.0.range = [2.7.6,3.0.0)
+units.0.requires.0.range = [2.7.7,3.0.0)
units.0.requires.1.namespace = org.eclipse.equinox.p2.eclipse.type
units.0.requires.1.name = bundle
@@ -26,7 +26,7 @@
units.0.provides.0.namespace = org.eclipse.equinox.p2.iu
units.0.provides.0.name = org.eclipse.objectteams.otequinox.configuration
-units.0.provides.0.version = 2.7.6.$qualifier$
+units.0.provides.0.version = 2.7.7.$qualifier$
units.0.instructions.install=\
installBundle(bundle:${artifact})
diff --git a/plugins/org.eclipse.objectteams.otequinox/about.ini b/plugins/org.eclipse.objectteams.otequinox/about.ini
index 4d7289a..0938d54 100644
--- a/plugins/org.eclipse.objectteams.otequinox/about.ini
+++ b/plugins/org.eclipse.objectteams.otequinox/about.ini
@@ -1,10 +1,10 @@
aboutText=Object Teams -- Equinox integration (OT/Equinox)\n\
\n\
-Version: 2.7.6\n\
+Version: 2.7.7\n\
\n\
-Part of Eclipse SimRel 2019-12\n\
+Part of Eclipse SimRel 2020-03\n\
\n\
-(c) Copyright Technical University Berlin and others, 2005, 2019\n\
+(c) Copyright Technical University Berlin and others, 2005, 2020\n\
Visit http://www.eclipse.org/objectteams\n\
\n\
diff --git a/plugins/org.eclipse.objectteams.otequinox/annotations/plugins/org/eclipse/equinox/log/ExtendedLogService.eea b/plugins/org.eclipse.objectteams.otequinox/annotations/plugins/org/eclipse/equinox/log/ExtendedLogService.eea
new file mode 100644
index 0000000..3f532a3
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/annotations/plugins/org/eclipse/equinox/log/ExtendedLogService.eea
@@ -0,0 +1,4 @@
+class org/eclipse/equinox/log/ExtendedLogService
+getLogger
+ (Lorg/osgi/framework/Bundle;Ljava/lang/String;)Lorg/eclipse/equinox/log/Logger;
+ (Lorg/osgi/framework/Bundle;Ljava/lang/String;)L1org/eclipse/equinox/log/Logger;
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/LoggerBridge.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/LoggerBridge.java
new file mode 100644
index 0000000..939fe94
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/LoggerBridge.java
@@ -0,0 +1,80 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ *
+ * Copyright 2020 GK Software SE
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Please visit http://www.objectteams.org for updates and contact.
+ *
+ * Contributors:
+ * Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.log.Logger;
+import org.eclipse.osgi.framework.log.FrameworkLogEntry;
+import org.osgi.service.log.LogService;
+
+/**
+ * Utility to bridge from IStatus logging to {@link Logger}.
+ */
+public class LoggerBridge {
+
+ public static void log(Logger logger, IStatus status) {
+ logger.log(LoggerBridge.getLog(status), LoggerBridge.getLevel(status), status.getMessage(), status.getException());
+ }
+
+ // --- copied from org.eclipse.core.internal.runtime.PlatformLogWriter.getLog(IStatus): ---
+
+ public static final String EQUINOX_LOGGER_NAME = "org.eclipse.equinox.logger"; //$NON-NLS-1$
+
+ static FrameworkLogEntry getLog(IStatus status) {
+ Throwable t = status.getException();
+ ArrayList<FrameworkLogEntry> childlist = new ArrayList<>();
+
+ int stackCode = t instanceof CoreException ? 1 : 0;
+ // ensure a substatus inside a CoreException is properly logged
+ if (stackCode == 1) {
+ IStatus coreStatus = ((CoreException) t).getStatus();
+ if (coreStatus != null) {
+ childlist.add(getLog(coreStatus));
+ }
+ }
+
+ if (status.isMultiStatus()) {
+ IStatus[] children = status.getChildren();
+ for (IStatus child : children) {
+ childlist.add(getLog(child));
+ }
+ }
+
+ FrameworkLogEntry[] children = childlist.size() == 0 ? null : childlist.toArray(new FrameworkLogEntry[childlist.size()]);
+
+ return new FrameworkLogEntry(status, status.getPlugin(), status.getSeverity(), status.getCode(), status.getMessage(), stackCode, t, children);
+ }
+
+ @SuppressWarnings("deprecation")
+ public static int getLevel(IStatus status) {
+ switch (status.getSeverity()) {
+ case IStatus.ERROR :
+ return LogService.LOG_ERROR;
+ case IStatus.WARNING :
+ return LogService.LOG_WARNING;
+ case IStatus.INFO :
+ return LogService.LOG_INFO;
+ case IStatus.OK :
+ return LogService.LOG_DEBUG;
+ case IStatus.CANCEL :
+ default :
+ return 32; // unknown
+ }
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/TransformerPlugin.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/TransformerPlugin.java
index ffa20a4..2727ef2 100644
--- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/TransformerPlugin.java
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/TransformerPlugin.java
@@ -1,7 +1,7 @@
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
- * Copyright 2013, 2015 GK Software AG
+ * Copyright 2013, 2020 GK Software SE
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -25,22 +25,22 @@
import java.util.List;
import java.util.Map;
-import org.eclipse.core.internal.runtime.PlatformLogWriter;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IExtensionRegistry;
-import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.equinox.log.ExtendedLogReaderService;
import org.eclipse.equinox.log.ExtendedLogService;
import org.eclipse.equinox.log.LogFilter;
import org.eclipse.equinox.log.Logger;
+import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.objectteams.internal.osgi.weaving.AspectBinding;
import org.eclipse.objectteams.internal.osgi.weaving.AspectBindingRegistry;
import org.eclipse.objectteams.internal.osgi.weaving.AspectPermissionManager;
import org.eclipse.objectteams.internal.osgi.weaving.DelegatingTransformer.OTAgentNotInstalled;
+import org.eclipse.objectteams.internal.osgi.weaving.LoggerBridge;
import org.eclipse.objectteams.internal.osgi.weaving.OTWeavingHook;
import org.eclipse.objectteams.otre.ClassLoaderAccess;
import org.objectteams.Team;
@@ -74,10 +74,10 @@
AspectBindingRegistry aspectBindingRegistry;
@Nullable AspectPermissionManager aspectPermissionManager;
- ILog log;
+ Logger log;
List<Team> teamInstances = new ArrayList<>();
- public InitializedPlugin(AspectBindingRegistry aspectBindingRegistry, @Nullable AspectPermissionManager permissionManager, ILog log) {
+ public InitializedPlugin(AspectBindingRegistry aspectBindingRegistry, @Nullable AspectPermissionManager permissionManager, Logger log) {
this.aspectBindingRegistry = aspectBindingRegistry;
this.aspectPermissionManager = permissionManager;
this.log = log;
@@ -116,7 +116,12 @@
result[i] = aspectBindings.get(i).aspectPlugin;
return result;
}
+
+ public void log(IStatus status) {
+ LoggerBridge.log(this.log, status);
+ }
}
+
private static @Nullable InitializedPlugin plugin;
/**
* Single point of access: either we get a fully initialized instance, or ISE is thrown.
@@ -188,15 +193,14 @@
otWeavingHook.activate(bundleContext, extensionService);
} catch (OTAgentNotInstalled e) {
registration.unregister();
- ILog log = acquireLog(bundleContext);
- log.log(new Status(IStatus.ERROR,
+ Logger log = acquireLog(bundleContext);
+ LoggerBridge.log(log, new Status(IStatus.ERROR,
bundleContext.getBundle().getSymbolicName(),
"Error activating OT/Equinox: "+e.getMessage()));
}
}
- @SuppressWarnings("restriction")
- private static ILog acquireLog(BundleContext bundleContext) {
+ private static Logger acquireLog(BundleContext bundleContext) {
setupLoggerContext(bundleContext);
ServiceTracker<ExtendedLogService,ExtendedLogService> tracker
= new ServiceTracker<ExtendedLogService,ExtendedLogService>(bundleContext, ExtendedLogService.class, null);
@@ -204,14 +208,13 @@
ExtendedLogService logService = tracker.getService();
Bundle bundle = bundleContext.getBundle();
Logger logger = logService.getLogger(bundle, OTEQUINOX_LOGGER_NAME);
- org.eclipse.core.internal.runtime.Log result = new org.eclipse.core.internal.runtime.Log(bundle, logger);
ServiceTracker<ExtendedLogReaderService, ExtendedLogReaderService> logReaderTracker
= new ServiceTracker<ExtendedLogReaderService,ExtendedLogReaderService>(bundleContext, ExtendedLogReaderService.class.getName(), null);
logReaderTracker.open();
ExtendedLogReaderService logReader = logReaderTracker.getService();
- final Logger equinoxLogger = logService.getLogger(bundle, org.eclipse.core.internal.runtime.PlatformLogWriter.EQUINOX_LOGGER_NAME);
+ final Logger equinoxLogger = logService.getLogger(bundle, LoggerBridge.EQUINOX_LOGGER_NAME);
// listen to log events from our logger and asynchronously dispatch them to the equinox logger
logReader.addLogListener(
@@ -228,15 +231,14 @@
}
}
);
- return result;
+ return logger;
}
private static void setupLoggerContext(BundleContext bundleContext) {
String bundleSymbolicName = bundleContext.getBundle().getSymbolicName();
Status dummyStatus = new Status(WARN_LEVEL, bundleSymbolicName, "no message");
- @SuppressWarnings("restriction")
- LogLevel logLevel = LogLevel.values()[PlatformLogWriter.getLevel(dummyStatus)];
+ LogLevel logLevel = LogLevel.values()[LoggerBridge.getLevel(dummyStatus)];
Map<String,LogLevel> levels = new HashMap<>();
levels.put(OTEQUINOX_LOGGER_NAME, logLevel);
@@ -289,7 +291,7 @@
Status status = new Status(IStatus.ERROR, TRANSFORMER_PLUGIN_ID, msg, ex);
final InitializedPlugin plugin = TransformerPlugin.plugin;
if (plugin != null) {
- plugin.log.log(status);
+ plugin.log(status);
} else {
System.err.println(msg);
ex.printStackTrace();
@@ -309,7 +311,7 @@
Status status = new Status(level, TRANSFORMER_PLUGIN_ID, "OT/Equinox: "+msg);
final InitializedPlugin plugin = TransformerPlugin.plugin;
if (plugin != null) {
- plugin.log.log(status);
+ plugin.log(status);
} else {
synchronized(TransformerPlugin.class) {
pendingLogEntries.add(status);
@@ -327,10 +329,10 @@
copy = pendingLogEntries;
pendingLogEntries = new ArrayList<>();
}
- for (IStatus status : copy) {
+ for (@NonNull IStatus status : copy) { // TODO: declare copy as List<@NonNull IStatus>
final InitializedPlugin plugin = TransformerPlugin.plugin;
if (plugin != null) {
- plugin.log.log(status);
+ plugin.log(status);
} else {
if (status.getCode() == IStatus.ERROR)
System.err.println(status.getMessage());
diff --git a/releng/map/otdt.map.in b/releng/map/otdt.map.in
index 3e7700d..b4c505b 100644
--- a/releng/map/otdt.map.in
+++ b/releng/map/otdt.map.in
@@ -4,7 +4,7 @@
feature@org.eclipse.objectteams.otdt=GIT,repo=git://git.eclipse.org/gitroot/objectteams/org.eclipse.objectteams.git,path=features/org.eclipse.objectteams.otdt.feature
feature@org.eclipse.objectteams.otdt.source.feature=GIT,repo=git://git.eclipse.org/gitroot/objectteams/org.eclipse.objectteams.git,path=features/org.eclipse.objectteams.otdt.source.feature
feature@org.eclipse.objectteams.otdt.core.patch=GIT,repo=git://git.eclipse.org/gitroot/objectteams/org.eclipse.objectteams.git,path=features/org.eclipse.objectteams.otdt.core.patch
-feature@org.eclipse.objectteams.otequinox=GIT,repo=git://git.eclipse.org/gitroot/objectteams/org.eclipse.objectteams.git,path=features/org.eclipse.objectteams.otequinox.feature,tag=builds/201912111741
+feature@org.eclipse.objectteams.otequinox=GIT,repo=git://git.eclipse.org/gitroot/objectteams/org.eclipse.objectteams.git,path=features/org.eclipse.objectteams.otequinox.feature
feature@org.eclipse.objectteams.otequinox.otre=GIT,repo=git://git.eclipse.org/gitroot/objectteams/org.eclipse.objectteams.git,path=features/org.eclipse.objectteams.otequinox.otre.feature,tag=builds/201809081701
feature@org.eclipse.objectteams.otequinox.turbo=GIT,repo=git://git.eclipse.org/gitroot/objectteams/org.eclipse.objectteams.git,path=features/org.eclipse.objectteams.otequinox.turbo.feature,tag=builds/201506091717
@@ -24,7 +24,7 @@
plugin@org.eclipse.objectteams.otre=GIT,repo=git://git.eclipse.org/gitroot/objectteams/org.eclipse.objectteams.git,path=plugins/org.eclipse.objectteams.otre,tag=builds/201806120901
plugin@org.eclipse.objectteams.otredyn=GIT,repo=git://git.eclipse.org/gitroot/objectteams/org.eclipse.objectteams.git,path=plugins/org.eclipse.objectteams.otredyn,tag=builds/201912111741
!the following is also referenced in otdt.doc/buildDoc.xml (plugin-name without version):
-plugin@org.eclipse.objectteams.otequinox=GIT,repo=git://git.eclipse.org/gitroot/objectteams/org.eclipse.objectteams.git,path=plugins/org.eclipse.objectteams.otequinox,tag=builds/201912111741
+plugin@org.eclipse.objectteams.otequinox=GIT,repo=git://git.eclipse.org/gitroot/objectteams/org.eclipse.objectteams.git,path=plugins/org.eclipse.objectteams.otequinox
fragment@org.eclipse.objectteams.otequinox.turbo=GIT,repo=git://git.eclipse.org/gitroot/objectteams/org.eclipse.objectteams.git,path=plugins/org.eclipse.objectteams.otequinox.turbo,tag=builds/201506091717
plugin@org.eclipse.objectteams.eclipse.monitor=GIT,repo=git://git.eclipse.org/gitroot/objectteams/org.eclipse.objectteams.git,path=plugins/org.eclipse.objectteams.eclipse.monitor,tag=builds/201606070956