[390105] Publish before start servers synchronization problem
diff --git a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java
index 19d6ec0..13fdda4 100644
--- a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java
+++ b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java
@@ -1898,7 +1898,7 @@
job.schedule();
}
- protected IStatus publishBeforeStart(IProgressMonitor monitor, boolean synchronous){
+ protected IStatus publishBeforeStart(IProgressMonitor monitor, final StartJob startJob, final boolean synchronous){
// check if we need to publish
byte pub = StartJob.PUBLISH_NONE;
@@ -1917,22 +1917,53 @@
pubJob.addJobChangeListener(new JobChangeAdapter(){
public void done(IJobChangeEvent event) {
IStatus status = event.getResult();
- if (status != null && status.getSeverity() == IStatus.ERROR)
- pubStatus[0] = status;
+ if (status != null && status.getSeverity() == IStatus.ERROR) {
+ pubStatus[0] = status;
+ if (Trace.INFO) {
+ Trace.trace(Trace.STRING_INFO,
+ "Skipping server start job schedule since the server publish failed on a publish before start server.");
+ }
+ } else {
+ if (Trace.INFO) {
+ Trace.trace(Trace.STRING_INFO,
+ "Scheduling server start job after successful publish.");
+ }
+ // Schedule the server start job since the publish operation is completed successfully.
+ startJob.schedule();
+
+ try {
+ if (synchronous)
+ startJob.join();
+ } catch (InterruptedException e) {
+ if (Trace.WARNING) {
+ Trace.trace(Trace.STRING_WARNING, "Error waiting for job", e);
+ }
+ }
+ }
}
});
-
pubJob.schedule();
- try{
+ try {
if (synchronous)
pubJob.join();
-
- }
- catch (InterruptedException ie){
+ } catch (InterruptedException ie) {
return Status.CANCEL_STATUS;
}
+ } else {
+ // Schedule the server start since a publish is not needed so
+ // Schedule the server start job since the publish operation is completed successfully.
+ startJob.schedule();
+
+ try {
+ if (synchronous)
+ startJob.join();
+ } catch (InterruptedException e) {
+ if (Trace.WARNING) {
+ Trace.trace(Trace.STRING_WARNING, "Error waiting for job", e);
+ }
+ }
}
return pubStatus[0];
}
@@ -1996,20 +2027,10 @@
// make sure that the delegate is loaded and the server state is correct
loadAdapter(ServerBehaviourDelegate.class, null);
- boolean synchronous = ((ServerType)getServerType()).synchronousStart();
- IStatus status = publishBeforeStart(monitor,synchronous);
-
- if (status != null && status.getSeverity() == IStatus.ERROR){
- if (Trace.FINEST) {
- Trace.trace(Trace.STRING_FINEST, "Failed publish job during start routine");
- }
- return;
- }
-
StartJob startJob = new StartJob(mode2);
// 287442 - only do publish after start if the server start is successful.
final IProgressMonitor monitor2 = monitor;
- final boolean synchronous2 = synchronous;
+ final boolean synchronous = ((ServerType)getServerType()).synchronousStart();
startJob.addJobChangeListener(new JobChangeAdapter() {
public void done(IJobChangeEvent event) {
IStatus resultStatus = event.getResult();
@@ -2019,17 +2040,29 @@
"Skipping auto publish after server start since the server start failed.");
}
} else {
- publishAfterStart(monitor2,synchronous2,null);
+ publishAfterStart(monitor2,synchronous,null);
}
}
});
- startJob.schedule();
- try {
- if(synchronous)
- startJob.join();
- } catch (InterruptedException e) {
- if (Trace.WARNING) {
- Trace.trace(Trace.STRING_WARNING, "Error waiting for job", e);
+ // Forces synchronous start since this method is supposed to wait until the publish operation is completed.
+ IStatus status = publishBeforeStart(monitor, startJob, true);
+
+ if (status != null && status.getSeverity() == IStatus.ERROR){
+ if (Trace.FINEST) {
+ Trace.trace(Trace.STRING_FINEST, "Failed publish job during start routine");
+ }
+ return;
+ }
+
+ if (((ServerType)getServerType()).startBeforePublish()) {
+ startJob.schedule();
+ try {
+ if(synchronous)
+ startJob.join();
+ } catch (InterruptedException e) {
+ if (Trace.WARNING) {
+ Trace.trace(Trace.STRING_WARNING, "Error waiting for job", e);
+ }
}
}
}
@@ -2047,18 +2080,6 @@
// make sure that the delegate is loaded and the server state is correct
loadAdapter(ServerBehaviourDelegate.class, null);
- boolean synchronous = ((ServerType)getServerType()).synchronousStart();
- IStatus status = publishBeforeStart(null,synchronous);
-
- if (status != null && status.getSeverity() == IStatus.ERROR){
- if (Trace.FINEST) {
- Trace.trace(Trace.STRING_FINEST, "Failed publish job during start routine");
- }
- if (opListener != null)
- opListener.done(Status.OK_STATUS);
- return;
- }
-
// check the publish flag (again) to determine when to call opListener.done
byte pub = StartJob.PUBLISH_NONE;
if (ServerCore.isAutoPublishing() && shouldPublish()) {
@@ -2080,8 +2101,22 @@
}
});
}
+
+ final boolean synchronous = ((ServerType)getServerType()).synchronousStart();
+ // For publish before start servers, the start job will only be kicked off if the publishing
+ // operation is completed successfully.
+ IStatus status = publishBeforeStart(null, startJob, synchronous);
+
+ if (status != null && status.getSeverity() == IStatus.ERROR){
+ if (Trace.FINEST) {
+ Trace.trace(Trace.STRING_FINEST, "Failed publish job during start routine");
+ }
+ if (opListener != null)
+ opListener.done(Status.OK_STATUS);
+ return;
+ }
+
// 287442 - only do publish after start if the server start is successful.
- final boolean synchronous2 = synchronous;
if (pub == StartJob.PUBLISH_AFTER) {
startJob.addJobChangeListener(new JobChangeAdapter() {
public void done(IJobChangeEvent event) {
@@ -2096,19 +2131,19 @@
opListener.done(Status.OK_STATUS);
}
else {
- publishAfterStart(null,synchronous2,opListener);
+ publishAfterStart(null,synchronous,opListener);
}
}
});
- }
- startJob.schedule();
-
- try {
- if(synchronous)
- startJob.join();
- } catch (InterruptedException e) {
- if (Trace.WARNING) {
- Trace.trace(Trace.STRING_WARNING, "Error waiting for job", e);
+ startJob.schedule();
+
+ try {
+ if(synchronous)
+ startJob.join();
+ } catch (InterruptedException e) {
+ if (Trace.WARNING) {
+ Trace.trace(Trace.STRING_WARNING, "Error waiting for job", e);
+ }
}
}
}
@@ -2120,15 +2155,6 @@
// make sure that the delegate is loaded and the server state is correct
loadAdapter(ServerBehaviourDelegate.class, monitor);
- IStatus status = publishBeforeStart(monitor,true);
-
- if (status != null && status.getSeverity() == IStatus.ERROR){
- if (Trace.FINEST) {
- Trace.trace(Trace.STRING_FINEST, "Failed publish job during start routine");
- }
- return;
- }
-
StartJob startJob = new StartJob(mode2);
// 287442 - only do publish after start if the server start is successful.
final IProgressMonitor monitor2 = monitor;
@@ -2145,13 +2171,25 @@
}
}
});
- startJob.schedule();
- try {
- startJob.join();
- } catch (InterruptedException e) {
- if (Trace.WARNING) {
- Trace.trace(Trace.STRING_WARNING, "Error waiting for job", e);
+ IStatus status = publishBeforeStart(monitor, startJob, true);
+
+ if (status != null && status.getSeverity() == IStatus.ERROR){
+ if (Trace.FINEST) {
+ Trace.trace(Trace.STRING_FINEST, "Failed publish job during start routine");
+ }
+ return;
+ }
+
+ if (((ServerType)getServerType()).startBeforePublish()) {
+ startJob.schedule();
+
+ try {
+ startJob.join();
+ } catch (InterruptedException e) {
+ if (Trace.WARNING) {
+ Trace.trace(Trace.STRING_WARNING, "Error waiting for job", e);
+ }
}
}
}
@@ -3154,6 +3192,7 @@
Trace.trace(Trace.STRING_FINEST, "Restarting server: " + getName());
}
+ ISchedulingRule curRule = null;
try {
try {
// synchronous restart
@@ -3170,24 +3209,21 @@
}
// if restart is not implemented by the server adopter
// lets provide a default implementation
+ // Ending the current rule setup by the RestartJob to prevent deadlock since the StopJob triggered
+ // by the stop(false) also setup the Server as the scheduling rule.
+ curRule = Job.getJobManager().currentRule();
+ Job.getJobManager().endRule(curRule);
stop(false);
- ISchedulingRule curRule = null;
- try {
- if (((ServerType)getServerType()).synchronousStart()) {
- curRule = Job.getJobManager().currentRule();
- Job.getJobManager().endRule(curRule);
- }
- start(launchMode, monitor);
- } finally {
- if (curRule != null) {
- Job.getJobManager().beginRule(curRule, monitor);
- }
- }
+ start(launchMode, monitor);
} catch (Exception e) {
if (Trace.SEVERE) {
Trace.trace(Trace.STRING_SEVERE, "Error restarting server", e);
}
return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorStartFailed, getName()), e);
+ } finally {
+ if (curRule != null) {
+ Job.getJobManager().beginRule(curRule, monitor);
+ }
}
return Status.OK_STATUS;
}