| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.geronimo.st.v30.core; |
| |
| import java.io.File; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.LinkedHashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.Timer; |
| |
| import javax.enterprise.deploy.spi.Target; |
| import javax.enterprise.deploy.spi.exceptions.DeploymentManagerCreationException; |
| import javax.management.MBeanServerConnection; |
| import javax.management.ObjectName; |
| import javax.management.remote.JMXConnector; |
| import javax.naming.directory.NoSuchAttributeException; |
| |
| import org.apache.geronimo.deployment.plugin.jmx.ExtendedDeploymentManager; |
| import org.apache.geronimo.deployment.plugin.jmx.JMXDeploymentManager; |
| import org.apache.geronimo.gbean.AbstractName; |
| import org.apache.geronimo.gbean.AbstractNameQuery; |
| import org.apache.geronimo.gbean.GBeanData; |
| import org.apache.geronimo.kernel.GBeanNotFoundException; |
| import org.apache.geronimo.kernel.InternalKernelException; |
| import org.apache.geronimo.kernel.Kernel; |
| import org.apache.geronimo.kernel.config.Configuration; |
| import org.apache.geronimo.kernel.config.InvalidConfigException; |
| import org.apache.geronimo.kernel.config.PersistentConfigurationList; |
| import org.apache.geronimo.kernel.repository.Artifact; |
| import org.apache.geronimo.kernel.util.IOUtils; |
| import org.apache.geronimo.st.core.GeronimoJMXConnectorFactory; |
| import org.apache.geronimo.st.core.GeronimoJMXConnectorFactory.JMXConnectorInfo; |
| import org.apache.geronimo.st.v30.core.commands.DeploymentCommandFactory; |
| import org.apache.geronimo.st.v30.core.internal.DependencyHelper; |
| import org.apache.geronimo.st.v30.core.internal.Messages; |
| import org.apache.geronimo.st.v30.core.internal.RemovedModuleHelper; |
| import org.apache.geronimo.st.v30.core.internal.Trace; |
| import org.apache.geronimo.st.v30.core.operations.ISharedLibEntryCreationDataModelProperties; |
| import org.apache.geronimo.st.v30.core.operations.SharedLibEntryCreationOperation; |
| import org.apache.geronimo.st.v30.core.operations.SharedLibEntryDataModelProvider; |
| import org.apache.geronimo.st.v30.core.osgi.AriesHelper; |
| import org.apache.geronimo.st.v30.core.osgi.AriesHelper.BundleInfo; |
| import org.apache.geronimo.st.v30.core.osgi.OSGiModuleHandler; |
| import org.apache.geronimo.st.v30.core.util.JMXKernel; |
| import org.apache.geronimo.st.v30.core.util.Utils; |
| import org.eclipse.core.commands.ExecutionException; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.MultiStatus; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.debug.core.DebugEvent; |
| import org.eclipse.debug.core.DebugPlugin; |
| import org.eclipse.debug.core.IDebugEventSetListener; |
| import org.eclipse.debug.core.ILaunch; |
| import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; |
| import org.eclipse.debug.core.ILaunchManager; |
| import org.eclipse.debug.core.model.IDebugTarget; |
| import org.eclipse.debug.core.model.IProcess; |
| import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector; |
| import org.eclipse.debug.core.sourcelookup.ISourceContainer; |
| import org.eclipse.debug.core.sourcelookup.containers.DefaultSourceContainer; |
| import org.eclipse.jdt.core.IClasspathEntry; |
| import org.eclipse.jdt.core.ToolFactory; |
| import org.eclipse.jdt.core.util.IClassFileReader; |
| import org.eclipse.jdt.debug.core.IJavaDebugTarget; |
| import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget; |
| import org.eclipse.jdt.internal.launching.RuntimeClasspathEntry; |
| import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; |
| import org.eclipse.jdt.launching.IRuntimeClasspathEntry; |
| import org.eclipse.jdt.launching.IVMInstall; |
| import org.eclipse.jdt.launching.JavaRuntime; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory; |
| import org.eclipse.wst.common.frameworks.datamodel.IDataModel; |
| import org.eclipse.wst.common.frameworks.datamodel.IDataModelOperation; |
| import org.eclipse.wst.server.core.IModule; |
| import org.eclipse.wst.server.core.IServer; |
| import org.eclipse.wst.server.core.IServerListener; |
| import org.eclipse.wst.server.core.ServerEvent; |
| import org.eclipse.wst.server.core.ServerPort; |
| import org.eclipse.wst.server.core.internal.IModulePublishHelper; |
| import org.eclipse.wst.server.core.internal.ProgressUtil; |
| import org.eclipse.wst.server.core.model.IModuleFile; |
| import org.eclipse.wst.server.core.model.IModuleFolder; |
| import org.eclipse.wst.server.core.model.IModuleResource; |
| import org.eclipse.wst.server.core.model.IModuleResourceDelta; |
| import org.eclipse.wst.server.core.model.ServerBehaviourDelegate; |
| import org.eclipse.wst.server.core.util.SocketUtil; |
| |
| /** |
| * @version $Rev$ $Date$ |
| */ |
| public class GeronimoServerBehaviourDelegate extends ServerBehaviourDelegate implements IGeronimoServerBehavior, IModulePublishHelper { |
| |
| public static final int TIMER_TASK_INTERVAL = 20; |
| |
| public static final int TIMER_TASK_DELAY = 20; |
| |
| private JMXKernel kernel = null; |
| |
| protected Timer stateTimer = null; |
| |
| protected SynchronizeProjectOnServerTask synchronizerTask = null; |
| |
| protected PingThread pingThread; |
| |
| protected transient IDebugEventSetListener processListener; |
| |
| public static final String ERROR_SETUP_LAUNCH_CONFIGURATION = "errorInSetupLaunchConfiguration"; |
| |
| private PublishStateListener publishStateListener; |
| |
| private Set<IProject> knownSourceProjects = null; |
| |
| private DefaultModuleHandler defaultModuleHandler; |
| private OSGiModuleHandler osgiModuleHandler; |
| |
| private RemovedModuleHelper removedModuleHelper; |
| |
| private boolean eclipseHotSwap; |
| |
| protected ClassLoader getContextClassLoader() { |
| return Kernel.class.getClassLoader(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.wst.server.core.model.ServerBehaviourDelegate#setupLaunchConfiguration(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy, |
| * org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| public void setupLaunchConfiguration(ILaunchConfigurationWorkingCopy wc, IProgressMonitor monitor) throws CoreException { |
| if (isRemote())// No launch for remote servers. |
| return; |
| |
| wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, getRuntimeClass()); |
| GeronimoRuntimeDelegate runtime = getRuntimeDelegate(); |
| |
| IVMInstall vmInstall = runtime.getVMInstall(); |
| if (vmInstall != null) { |
| wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_JRE_CONTAINER_PATH, |
| JavaRuntime.newJREContainerPath(vmInstall).toPortableString()); |
| } |
| |
| String existingProgArgs = null; |
| wc.setAttribute(ERROR_SETUP_LAUNCH_CONFIGURATION, (String)null); |
| |
| try{ |
| setupLaunchClasspath(wc, vmInstall); |
| existingProgArgs = wc.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, (String) null); |
| }catch (CoreException e){ |
| // Throwing a CoreException at this time will not accomplish anything useful as WTP will |
| // will essentially ignore it. Instead set a flag in the configuration that can |
| // subsequently be checked when an attempt is made to launch the server in |
| // GeronimoLaunchConfigurationDelegate.launch(). At that point a CoreException will be |
| // thrown that WTP will handle properly and will display an error dialog which is |
| // exactly what we want the GEP user to see. |
| wc.setAttribute(ERROR_SETUP_LAUNCH_CONFIGURATION, e.getMessage()); |
| } |
| GeronimoServerDelegate gsd = getServerDelegate(); |
| String programArgs = gsd.getProgramArgs(); |
| Trace.tracePoint("GeronimoServerBehaviourDelegate.v30", Activator.traceCore, "setupLaunchConfiguration serverProgramArgs", programArgs); |
| wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, programArgs); |
| |
| /* |
| programArgs = getServerProgramArgs(existingProgArgs, getServerDelegate()); |
| Trace.tracePoint("GeronimoServerBehaviourDelegate.v30", "setupLaunchConfiguration serverProgramArgs", |
| programArgs); |
| wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, programArgs); |
| */ |
| |
| String vmArgs = gsd.getVMArgs(); |
| Trace.tracePoint("GeronimoServerBehaviourDelegate.v30", Activator.traceCore, "setupLaunchConfiguration serverVMArgs", vmArgs); |
| wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, vmArgs); |
| } |
| |
| |
| /** |
| * @param launch |
| * @param launchMode |
| * @param monitor |
| * @throws CoreException |
| */ |
| synchronized protected void setupLaunch(ILaunch launch, String launchMode, IProgressMonitor monitor) throws CoreException { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.setupLaunch", launch, launchMode, monitor); |
| |
| String host = getServer().getHost(); |
| |
| if (!SocketUtil.isLocalhost(host)) { |
| return; |
| } |
| |
| ServerPort[] ports = getServer().getServerPorts(null); |
| for (int i = 0; i < ports.length; i++) { |
| ServerPort sp = ports[i]; |
| if (Utils.isPortInUse(host, ports[i].getPort(), 5)) { |
| throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, Messages.bind(Messages.errorPortInUse, Integer.toString(sp.getPort()), sp.getName()), null)); |
| } |
| } |
| |
| stopUpdateServerStateTask(); |
| setServerState(IServer.STATE_STARTING); |
| setMode(launchMode); |
| |
| IServerListener listener = new IServerListener() { |
| public void serverChanged(ServerEvent event) { |
| int eventKind = event.getKind(); |
| if ((eventKind & ServerEvent.STATE_CHANGE) != 0) { |
| int state = event.getServer().getServerState(); |
| if (state == IServer.STATE_STARTED |
| || state == IServer.STATE_STOPPED) { |
| GeronimoServerBehaviourDelegate.this.getServer().removeServerListener(this); |
| startUpdateServerStateTask(); |
| } |
| } |
| } |
| }; |
| |
| getServer().addServerListener(listener); |
| |
| Trace.tracePoint("Exit ", Activator.traceCore, "GeronimoServerBehaviourDelegate.setupLaunch"); |
| } |
| |
| /* |
| * Called when server is shutdown (Server view -> stop). |
| * |
| * @see org.eclipse.wst.server.core.model.ServerBehaviourDelegate#stop(boolean) |
| */ |
| public synchronized void stop(final boolean force) { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.stop", force); |
| |
| IServer server = getServer(); |
| |
| if (server.getServerState() != IServer.STATE_STOPPED) { |
| setServerState(IServer.STATE_STOPPING); |
| } |
| |
| // stop threads |
| stopPingThread(); |
| stopSynchronizeProjectOnServerTask(); |
| |
| // request shutdown |
| stopKernel(); |
| |
| // wait for shutdown |
| if (!waitForStopped(60 * 1000) || force) { |
| ILaunch launch = server.getLaunch(); |
| if (launch != null) { |
| Trace.trace(Trace.INFO, "Killing the geronimo server process", Activator.traceCore); //$NON-NLS-1$ |
| try { |
| launch.terminate(); |
| } catch (Exception e) { |
| Trace.trace(Trace.ERROR, "Error killing the geronimo server process", e, Activator.logCore); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| stopImpl(); |
| |
| Trace.tracePoint("Exit", Activator.traceCore, "GeronimoServerBehaviourDelegate.stop"); |
| } |
| |
| private boolean waitForStopped(long timeout) { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.waitForStopped", timeout); |
| |
| long started = System.currentTimeMillis(); |
| boolean stopped = false; |
| try { |
| while (System.currentTimeMillis() - started < timeout) { |
| if (isKernelAlive()) { |
| Thread.sleep(500); |
| } else { |
| stopped = true; |
| break; |
| } |
| } |
| } catch (InterruptedException e) { |
| // ignore |
| } |
| |
| Trace.tracePoint("Exit", Activator.traceCore, "GeronimoServerBehaviourDelegate.waitForStopped", stopped); |
| return stopped; |
| } |
| |
| /* |
| * Called when server process is killed (Console view -> stop). |
| */ |
| public void terminate() { |
| Trace.traceEntry(Activator.traceCore, "GeronimoServerBehaviourDelegate.terminate"); |
| |
| // stop threads |
| stopPingThread(); |
| stopSynchronizeProjectOnServerTask(); |
| |
| stopImpl(); |
| |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.terminate"); |
| } |
| |
| private void setStatus(IModule[] module, IStatus status, MultiStatus multiStatus) { |
| if (status.isOK()) { |
| setModulePublishState(module, IServer.PUBLISH_STATE_NONE); |
| setModuleStatus(module, null); |
| } else { |
| multiStatus.add(status); |
| setModuleStatus(module, status); |
| setModulePublishState(module, IServer.PUBLISH_STATE_UNKNOWN); |
| } |
| } |
| |
| void setKnownSourceProjects(Set<IProject> knownSourceProjects) { |
| this.knownSourceProjects = knownSourceProjects; |
| } |
| |
| boolean hasKnownSourceProject(List<IModule[]> moduleList) { |
| if (knownSourceProjects != null) { |
| for (IModule[] modules : moduleList) { |
| for (IModule module : modules) { |
| IProject project = module.getProject(); |
| if (project != null && !knownSourceProjects.contains(project)) { |
| Trace.trace(Trace.INFO, "Project " + project.getName() + " is not source lookup list.", Activator.traceCore); //$NON-NLS-1$ |
| return false; |
| } |
| } |
| } |
| } |
| return true; |
| } |
| |
| void resetSourceLookupList() { |
| Trace.trace(Trace.INFO, "Resetting source lookup list.", Activator.traceCore); //$NON-NLS-1$ |
| |
| // reset DefaultSourceContainer - that will force Eclipse to re-compute the source paths |
| AbstractSourceLookupDirector locator = (AbstractSourceLookupDirector) getServer().getLaunch().getSourceLocator(); |
| ISourceContainer[] oldContainers = locator.getSourceContainers(); |
| ISourceContainer[] newContainers = new ISourceContainer[oldContainers.length]; |
| System.arraycopy(oldContainers, 0, newContainers, 0, oldContainers.length); |
| DefaultSourceContainer newDefaultContainer = new DefaultSourceContainer(); |
| for (int i = 0; i < newContainers.length; i++) { |
| if (newDefaultContainer.getType().equals(newContainers[i].getType())) { |
| newContainers[i] = newDefaultContainer; |
| break; |
| } |
| } |
| locator.setSourceContainers(newContainers); |
| |
| // reset knownSourceProjects as they will be set once Eclipse re-computes the source paths |
| knownSourceProjects = null; |
| } |
| |
| /* |
| * Override this method to be able to process in-place shared lib entries and restart the shared lib configuration for all projects prior |
| * to publishing each IModule. |
| * |
| * This overridden method also fixes WTP Bugzilla 123676 to prevent duplicate repdeloys if both parent and child modules have deltas. |
| * |
| * (non-Javadoc) |
| * @see org.eclipse.wst.server.core.model.ServerBehaviourDelegate#publishModules(int, java.util.List, java.util.List, org.eclipse.core.runtime.MultiStatus, org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| protected void publishModules(int kind, List modules, List deltaKind, MultiStatus multi, IProgressMonitor monitor) { |
| Trace.traceEntry(Activator.traceCore, "GeronimoServerBehaviourDelegate.publishModules", publishKindToString(kind), Arrays.asList(modules), Arrays.asList(deltaKind), multi, monitor); |
| |
| // |
| // WTP publishes modules in reverse alphabetical order which does not account for possible |
| // dependencies between modules. If necessary reorder the publish order of the modules |
| // based on any discovered dependencies. |
| // |
| if (modules != null && modules.size() > 0) { |
| List list = getOrderedModules(this.getServer(),modules, deltaKind); |
| modules = (List) list.get(0); |
| deltaKind = (List) list.get(1); |
| // trace output |
| if (Activator.getDefault().isDebugging()) { |
| for (int i = 0; i < modules.size(); i++) { |
| IModule[] module = (IModule[]) modules.get(i); |
| Trace.trace(Trace.INFO, i + " " + Arrays.asList(module).toString() + " " |
| + deltaKindToString(((Integer) deltaKind.get(i)).intValue()), Activator.traceCore); |
| IModuleResourceDelta[] deltas = getPublishedResourceDelta(module); |
| traceModuleResourceDelta(deltas, " "); |
| } |
| } |
| } |
| |
| IStatus status = Status.OK_STATUS; |
| if (modules != null && modules.size() > 0 && getGeronimoServer().isInPlaceSharedLib()) { |
| List<IModule> rootModules = new ArrayList<IModule>(); |
| for(int i = 0; i < modules.size(); i++) { |
| IModule[] module = (IModule[]) modules.get(i); |
| if(!rootModules.contains(module[0])) { |
| rootModules.add(module[0]); |
| } |
| } |
| IModule[] toProcess = (IModule[])rootModules.toArray(new IModule[rootModules.size()]); |
| status = updateSharedLib(toProcess, ProgressUtil.getSubMonitorFor(monitor, 1000)); |
| } |
| |
| /* |
| * Build a map of root modules that need to be published. This is to ensure that |
| * we avoid redeploys and it guarantees that publishModule() is called once per |
| * deployed application. |
| */ |
| Map<String, ModuleDeltaList> publishMap = new LinkedHashMap<String, ModuleDeltaList>(); |
| for (int i = 0; i < modules.size(); i++) { |
| IModule[] module = (IModule[]) modules.get(i); |
| Integer moduleDeltaKind = (Integer) deltaKind.get(i); |
| IModule rootModule = module[0]; |
| |
| ModuleDeltaList list = publishMap.get(rootModule.getId()); |
| if (list == null) { |
| list = new ModuleDeltaList(rootModule); |
| publishMap.put(rootModule.getId(), list); |
| } |
| |
| if (module.length == 1) { |
| list.setRootModuleDelta(moduleDeltaKind.intValue()); |
| } else { |
| list.addChildModule(module, moduleDeltaKind.intValue()); |
| } |
| } |
| |
| // Reset source code lookup list - see GERONIMODEVTOOLS-763 for details. |
| if (ILaunchManager.DEBUG_MODE.equals(getServer().getMode()) && !hasKnownSourceProject(modules)) { |
| resetSourceLookupList(); |
| } |
| |
| if (status.isOK()) { |
| if (modules == null || modules.isEmpty()) { |
| return; |
| } |
| |
| if (monitor.isCanceled()) { |
| return; |
| } |
| |
| for (ModuleDeltaList moduleList : publishMap.values()) { |
| IModule[] rootModule = moduleList.getRootModule(); |
| if (GeronimoUtils.isEBAModule(rootModule[0])) { |
| publishEBAModule(kind, multi, monitor, moduleList); |
| } else if (GeronimoUtils.isEarModule(rootModule[0])) { |
| publishEARModule(kind, multi, monitor, moduleList); |
| } else if (GeronimoUtils.isWebModule(rootModule[0]) || GeronimoUtils.isBundleModule(rootModule[0])) { |
| publishSingleModule(kind, multi, monitor, moduleList); |
| } else { |
| publishEntireModule(kind, multi, monitor, moduleList); |
| } |
| } |
| |
| } else { |
| multi.add(status); |
| } |
| |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.publishModules"); |
| } |
| |
| private void publishEBAModule(int kind, MultiStatus multi, IProgressMonitor monitor, ModuleDeltaList moduleList) { |
| Trace.traceEntry(Activator.traceCore, "GeronimoServerBehaviourDelegate.publishEBAModule", Arrays.toString(moduleList.getRootModule())); |
| |
| Map<IModule[], IStatus> statusMap = new HashMap<IModule[], IStatus>(); |
| |
| if (getServerDelegate().isNoRedeploy() && !isRemote()) { |
| if (moduleList.hasChangedChildModulesOnly(true)) { |
| List<ModuleInfo> childModules = moduleList.getChildModules(); |
| for (ModuleInfo module : childModules) { |
| if (module.delta == CHANGED) { |
| // changed module - try to do replacement |
| IModuleResourceDelta[] delta = getPublishedResourceDelta(module.module); |
| IModuleResourceDelta[] nonClassDelta = FilteredClassResourceDelta.getChangedClassExcludeDelta(delta); |
| if (Activator.getDefault().isDebugging()) { |
| Trace.trace(Trace.INFO, "Non-modified class delta for " + module, Activator.traceCore); |
| traceModuleResourceDelta(nonClassDelta, " "); |
| } |
| IStatus status = tryFileReplace(module.module, nonClassDelta); |
| if (status == null) { |
| // replace not performed - must redeploy bundle or entire application |
| } else if (status.isOK()) { |
| boolean containsModifiedClasses = DeploymentUtils.containsChangedClassResources(delta); |
| if (containsModifiedClasses) { |
| // replace performed but we have modified classes to deploy |
| // set remaining resource delta to process |
| IModuleResourceDelta[] classDelta = FilteredClassResourceDelta.getChangedClassIncludeDelta(delta); |
| if (Activator.getDefault().isDebugging()) { |
| Trace.trace(Trace.INFO, "Modified class delta for " + module, Activator.traceCore); |
| traceModuleResourceDelta(classDelta, " "); |
| } |
| module.resourceDelta = classDelta; |
| } else { |
| // replace performed and was successful |
| statusMap.put(module.module, status); |
| } |
| } else { |
| // replace performed but failed |
| statusMap.put(module.module, status); |
| } |
| } else { |
| // non-changed module |
| statusMap.put(module.module, Status.OK_STATUS); |
| } |
| } |
| |
| if (statusMap.size() == childModules.size()) { |
| // replacement was possible for all changed child modules - we're done |
| for (Map.Entry<IModule[], IStatus> entry : statusMap.entrySet()) { |
| setStatus(entry.getKey(), entry.getValue(), multi); |
| } |
| setStatus(moduleList.getRootModule(), Status.OK_STATUS, multi); |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.publishEBAModule", "File replace"); |
| return; |
| } |
| |
| // fall-through: replacement was not possible for at least one child module or more work to do |
| } |
| } |
| |
| boolean refreshOSGiBundle = getServerDelegate().isRefreshOSGiBundle(); |
| if (refreshOSGiBundle && moduleList.hasChangedChildModulesOnly(false)) { |
| AbstractName ebaName = getApplicationGBeanName(moduleList.getRootModule()[0]); |
| if (ebaName != null) { |
| for (ModuleInfo module : moduleList.getChildModules()) { |
| IStatus status = statusMap.get(module.module); |
| if (status == null) { |
| if (module.delta == CHANGED) { |
| status = refreshBundle(ebaName, module); |
| } else { |
| status = Status.OK_STATUS; |
| } |
| } |
| setStatus(module.module, status, multi); |
| } |
| setStatus(moduleList.getRootModule(), Status.OK_STATUS, multi); |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.publishEBAModule", "Bundle update"); |
| return; |
| } |
| } |
| |
| // deploy the entire module |
| publishEntireModule(kind, multi, monitor, moduleList); |
| |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.publishEBAModule"); |
| } |
| |
| private void publishEARModule(int kind, MultiStatus multi, IProgressMonitor monitor, ModuleDeltaList moduleList) { |
| Trace.traceEntry(Activator.traceCore, "GeronimoServerBehaviourDelegate.publishEARModule", Arrays.toString(moduleList.getRootModule())); |
| |
| if (getServerDelegate().isNoRedeploy() && !isRemote()) { |
| if (moduleList.hasChangedChildModulesOnly(true)) { |
| List<ModuleInfo> childModules = moduleList.getChildModules(); |
| Map<IModule[], IStatus> statusMap = new HashMap<IModule[], IStatus>(); |
| |
| for (ModuleInfo module : childModules) { |
| if (module.delta == CHANGED) { |
| // changed module - try to do replacement |
| IModuleResourceDelta[] delta = getPublishedResourceDelta(module.module); |
| IStatus status = tryFileReplace(module.module, delta); |
| if (status == null) { |
| // replacement was not possible - must redeploy the whole ear |
| break; |
| } else { |
| statusMap.put(module.module, status); |
| } |
| } else { |
| // non-changed module |
| statusMap.put(module.module, Status.OK_STATUS); |
| } |
| } |
| |
| if (statusMap.size() == childModules.size()) { |
| // replacement was possible for all changed child modules - we're done |
| for (Map.Entry<IModule[], IStatus> entry : statusMap.entrySet()) { |
| setStatus(entry.getKey(), entry.getValue(), multi); |
| } |
| setStatus(moduleList.getRootModule(), Status.OK_STATUS, multi); |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.publishEARModule", "File replace"); |
| return; |
| } |
| |
| // fall-through: replacement was not possible for at least one child module - deploy the entire module |
| } |
| } |
| |
| // deploy the entire module |
| publishEntireModule(kind, multi, monitor, moduleList); |
| |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.publishEARModule"); |
| } |
| |
| private void publishSingleModule(int kind, MultiStatus multi, IProgressMonitor monitor, ModuleDeltaList moduleList) { |
| Trace.traceEntry(Activator.traceCore, "GeronimoServerBehaviourDelegate.publishSingleModule", Arrays.toString(moduleList.getRootModule())); |
| |
| if (getServerDelegate().isNoRedeploy() && !isRemote()) { |
| if (moduleList.getEffectiveRootDelta() == CHANGED) { |
| // contents changed - try to do replacement |
| IModule[] rootModule = moduleList.getRootModule(); |
| IModuleResourceDelta[] delta = getPublishedResourceDelta(rootModule); |
| IStatus status = tryFileReplace(rootModule, delta); |
| if (status != null) { |
| // replacement was possible - we're done |
| setStatus(rootModule, status, multi); |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.publishSingleModule", "File replace"); |
| return; |
| } |
| |
| // fall-through: replacement was not possible - deploy the entire module |
| } |
| } |
| |
| // deploy the entire module |
| publishEntireModule(kind, multi, monitor, moduleList); |
| |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.publishSingleModule"); |
| } |
| |
| private void publishEntireModule(int kind, MultiStatus multi, IProgressMonitor monitor, ModuleDeltaList moduleList) { |
| Trace.traceEntry(Activator.traceCore, "GeronimoServerBehaviourDelegate.publishEntireModule", Arrays.toString(moduleList.getRootModule())); |
| |
| IStatus status = publishModule(kind, moduleList.getRootModule(), moduleList.getEffectiveRootDelta(), ProgressUtil.getSubMonitorFor(monitor, 3000)); |
| if (status != null && !status.isOK()) { |
| multi.add(status); |
| } else { |
| for (ModuleInfo moduleDelta : moduleList.getChildModules()) { |
| setModulePublishState(moduleDelta.module, IServer.PUBLISH_STATE_NONE); |
| setModuleStatus(moduleDelta.module, null); |
| } |
| } |
| |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.publishEntireModule", status); |
| } |
| |
| private AbstractName getApplicationGBeanName(IModule ebaModule) { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.getApplicationGBeanName", ebaModule); |
| IServer server = getServer(); |
| AbstractName ebaName = null; |
| try { |
| String configId = DeploymentUtils.getConfigId(server, ebaModule); |
| ExtendedDeploymentManager dm = (ExtendedDeploymentManager) DeploymentCommandFactory.getDeploymentManager(server); |
| ebaName = dm.getApplicationGBeanName(Artifact.create(configId)); |
| } catch (CoreException e) { |
| Trace.trace(Trace.WARNING, "Error getting gbean name", e, Activator.traceCore); |
| } |
| Trace.tracePoint("Exit", Activator.traceCore, "GeronimoServerBehaviourDelegate.getApplicationGBeanName", ebaName); |
| return ebaName; |
| } |
| |
| private IStatus refreshBundle(AbstractName ebaName, ModuleInfo module) { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.refreshBundle", ebaName, module); |
| IModule ebaModule = module.module[0]; |
| IModule bundleModule = module.module[1]; |
| try { |
| ExtendedDeploymentManager dm = (ExtendedDeploymentManager) DeploymentCommandFactory.getDeploymentManager(getServer()); |
| |
| BundleInfo bundleInfo = AriesHelper.getBundleInfo(bundleModule.getProject()); |
| long bundleId = dm.getEBAContentBundleId(ebaName, bundleInfo.getSymbolicName(), bundleInfo.getVersion().toString()); |
| |
| if (bundleId == -1) { |
| return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.bind(Messages.REFRESH_NO_BUNDLE_FAIL, |
| new String[] {bundleModule.getProject().getName(), ebaModule.getProject().getName()})); |
| } |
| |
| /* |
| * Try class hot swap first and if it fails fallback to regular bundle update. |
| */ |
| ClassReplaceResult result = refreshBundleClasses(dm, ebaName, module, bundleId); |
| if (result != ClassReplaceResult.SUCCESS) { |
| File file = DeploymentUtils.getTargetFile(getServer(), bundleModule); |
| dm.updateEBAContent(ebaName, bundleId, file); |
| if (result == ClassReplaceResult.FAIL_FORCE_GC) { |
| invokeGC(); |
| } |
| } |
| |
| } catch (Exception e) { |
| return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.REFRESH_FAIL, e); |
| } |
| |
| Trace.tracePoint("Exit ", Activator.traceCore, "GeronimoServerBehaviourDelegate.refreshBundle"); |
| |
| return Status.OK_STATUS; |
| } |
| |
| private enum ClassReplaceResult { SUCCESS, FAIL, FAIL_FORCE_GC }; |
| |
| private ClassReplaceResult refreshBundleClasses(ExtendedDeploymentManager dm, AbstractName ebaName, ModuleInfo module, long bundleId) throws Exception { |
| Trace.traceEntry(Activator.traceCore, "GeronimoServerBehaviourDelegate.refreshBundleClasses", ebaName, module, bundleId); |
| // check if class hot swap is supported |
| if (!dm.isRedefineClassesSupported()) { |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.refreshBundleClasses", "Class redefinition is not supported"); |
| return ClassReplaceResult.FAIL; |
| } |
| // ensure only classes have changed |
| IModuleResourceDelta[] delta = module.resourceDelta; |
| if (delta == null) { |
| delta = getPublishedResourceDelta(module.module); |
| } |
| IModuleResource[] classResources = DeploymentUtils.getChangedClassResources(delta); |
| if (classResources == null) { |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.refreshBundleClasses", "Non-class resource modifications found"); |
| return ClassReplaceResult.FAIL; |
| } |
| // create temp. zip with the changes |
| File changeSetFile = DeploymentUtils.createChangeSetFile(classResources); |
| if (changeSetFile == null) { |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.refreshBundleClasses", "Error creating file with resource modifications"); |
| return ClassReplaceResult.FAIL; |
| } |
| if (eclipseHotSwap) { |
| // debug mode - Eclipse will do class hot swap for us |
| IDebugTarget target = getServer().getLaunch().getDebugTarget(); |
| if (isOutOfSynch(target, classResources)) { |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.refreshBundleClasses", "Eclipse HCR failed"); |
| return ClassReplaceResult.FAIL_FORCE_GC; |
| } else { |
| // save changes only |
| boolean result = dm.updateEBAArchive(ebaName, bundleId, changeSetFile, true); |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.refreshBundleClasses", "Eclipse HCR - updated class files only", result); |
| return ClassReplaceResult.SUCCESS; |
| } |
| } else { |
| // non-debug mode - try class hot swap |
| if (!dm.hotSwapEBAContent(ebaName, bundleId, changeSetFile, true)) { |
| changeSetFile.delete(); |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.refreshBundleClasses", "Bundle class hot swap cannot be preformed"); |
| return ClassReplaceResult.FAIL; |
| } else { |
| changeSetFile.delete(); |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.refreshBundleClasses", "Bundle class hot swap was succesfully preformed"); |
| return ClassReplaceResult.SUCCESS; |
| } |
| } |
| } |
| |
| private boolean isOutOfSynch(IDebugTarget target, IModuleResource[] classResources) { |
| Trace.traceEntry(Activator.traceCore, "GeronimoServerBehaviourDelegate.isOutOfSynch"); |
| if (target instanceof JDIDebugTarget) { |
| JDIDebugTarget javaTarget = (JDIDebugTarget) target; |
| for (IModuleResource resource : classResources) { |
| String path = null; |
| IFile srcIFile = (IFile) resource.getAdapter(IFile.class); |
| if (srcIFile != null) { |
| path = srcIFile.getLocation().toOSString(); |
| } else { |
| File srcFile = (File) resource.getAdapter(File.class); |
| path = srcFile.getAbsolutePath(); |
| } |
| |
| IClassFileReader reader = ToolFactory.createDefaultClassFileReader(path, IClassFileReader.CLASSFILE_ATTRIBUTES); |
| if (reader != null) { |
| String className = new String(reader.getClassName()).replace('/', '.'); |
| if (javaTarget.isOutOfSynch(className)) { |
| // out-of-synch class found |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.isOutOfSynch", "Out-of-synch class found", className); |
| return true; |
| } |
| } |
| } |
| } |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.isOutOfSynch"); |
| return false; |
| } |
| |
| private boolean isEclipseHotSwapEnabled() { |
| Trace.traceEntry(Activator.traceCore, "GeronimoServerBehaviourDelegate.isEclipseHotSwapEnabled"); |
| boolean enabled = false; |
| IServer server = getServer(); |
| if (ILaunchManager.DEBUG_MODE.equals(server.getMode())) { |
| ILaunch launch = server.getLaunch(); |
| if (launch != null) { |
| IDebugTarget target = launch.getDebugTarget(); |
| if (target instanceof IJavaDebugTarget) { |
| IJavaDebugTarget javaTarget = (IJavaDebugTarget) target; |
| javaTarget.addHotCodeReplaceListener(new HotCodeReplaceListener()); |
| enabled = javaTarget.supportsHotCodeReplace(); |
| } |
| } |
| } |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.isEclipseHotSwapEnabled", enabled); |
| return enabled; |
| } |
| |
| private static class ModuleInfo { |
| private final IModule[] module; |
| private int delta = NO_CHANGE; |
| private IModuleResourceDelta[] resourceDelta; |
| |
| public ModuleInfo(IModule[] module, int delta) { |
| this.module = module; |
| this.delta = delta; |
| } |
| |
| public String toString() { |
| return Arrays.toString(module); |
| } |
| } |
| |
| private static class ModuleDeltaList { |
| |
| private ModuleInfo root; |
| private List<ModuleInfo> children; |
| |
| public ModuleDeltaList(IModule rootModule) { |
| this.root = new ModuleInfo(new IModule [] {rootModule}, NO_CHANGE); |
| this.children = new ArrayList<ModuleInfo>(); |
| } |
| |
| public IModule[] getRootModule() { |
| return root.module; |
| } |
| |
| public int getEffectiveRootDelta() { |
| if (root.delta == NO_CHANGE) { |
| for (ModuleInfo child : children) { |
| if (child.delta == ADDED || child.delta == REMOVED || child.delta == CHANGED) { |
| return CHANGED; |
| } |
| } |
| } |
| return root.delta; |
| } |
| |
| public void setRootModuleDelta(int moduleDelta) { |
| root.delta = moduleDelta; |
| } |
| |
| public void addChildModule(IModule[] module, int moduleDelta) { |
| children.add(new ModuleInfo(module, moduleDelta)); |
| } |
| |
| public List<ModuleInfo> getChildModules() { |
| return children; |
| } |
| |
| public boolean hasChangedChildModulesOnly(boolean allChangedAllowed) { |
| int changed = getChangedChildModulesOnly(); |
| if (changed > 0) { |
| if (allChangedAllowed) { |
| return true; |
| } else { |
| if (children.size() == 1) { |
| // special case: always return true if module only has one child module |
| return true; |
| } else { |
| return (changed < children.size()); |
| } |
| } |
| } |
| return false; |
| } |
| |
| /* |
| * Returns number of "changed" child modules. |
| * Returns -1 if a single "added" or "removed" child module is found or a root module is modified. |
| */ |
| public int getChangedChildModulesOnly() { |
| if (root.delta == NO_CHANGE) { |
| int changed = 0; |
| for (ModuleInfo child : children) { |
| if (child.delta == ADDED || child.delta == REMOVED) { |
| return -1; |
| } else if (child.delta == CHANGED) { |
| changed++; |
| } |
| } |
| return changed; |
| } |
| return -1; |
| } |
| } |
| |
| /* |
| * This method is used to invoke DependencyHelper of different version |
| */ |
| protected List getOrderedModules(IServer server, List modules, List deltaKind) { |
| DependencyHelper dh = new DependencyHelper(); |
| List list = dh.reorderModules(this.getServer(),modules, deltaKind); |
| return list; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.wst.server.core.model.ServerBehaviourDelegate#publishModule(int, |
| * int, org.eclipse.wst.server.core.IModule[], |
| * org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| public void publishModule(int kind, int deltaKind, IModule[] module, IProgressMonitor monitor) throws CoreException { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.publishModule", publishKindToString(kind), deltaKindToString(deltaKind), Arrays.asList(module), monitor); |
| try { |
| //NO_CHANGE need if app is associated but not started and no delta |
| if (deltaKind == NO_CHANGE && module.length == 1) { |
| invokeCommand(deltaKind, module[0], monitor); |
| } |
| else if (deltaKind == CHANGED || deltaKind == ADDED || deltaKind == REMOVED) { |
| invokeCommand(deltaKind, module[0], monitor); |
| } |
| setModuleStatus(module, null); |
| setModulePublishState(module, IServer.PUBLISH_STATE_NONE); |
| } |
| catch (CoreException e) { |
| // |
| // Set the parent module publish state to UNKNOWN so that WTP will display "Republish" instead |
| // "Synchronized" for the server state, and set the module status to an error message |
| // for the GEP end-user to see. |
| // |
| setModuleStatus(module, new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Error publishing module to server")); |
| setModulePublishState(module, IServer.PUBLISH_STATE_UNKNOWN); |
| setModuleState(module, IServer.STATE_UNKNOWN); |
| throw e; |
| } |
| |
| Trace.tracePoint("Exit ", Activator.traceCore, "GeronimoServerBehaviourDelegate.publishModule"); |
| } |
| |
| @Override |
| public void publishStart(IProgressMonitor monitor) throws CoreException { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.publishStart", monitor); |
| Trace.tracePoint("Exit ", Activator.traceCore, "GeronimoServerBehaviourDelegate.publishStart"); |
| } |
| |
| @Override |
| public void publishFinish(IProgressMonitor monitor) throws CoreException { |
| doPublishFinish(monitor); |
| } |
| |
| private void doPublishFinish(IProgressMonitor monitor) throws CoreException { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.publishFinish", monitor); |
| |
| IModule[] modules = this.getServer().getModules(); |
| boolean allpublished = true; |
| for (int i = 0; i < modules.length; i++) { |
| int state = getServer().getModulePublishState(new IModule[] { modules[i] }); |
| if (state != IServer.PUBLISH_STATE_NONE) { |
| allpublished = false; |
| break; |
| } |
| } |
| if (allpublished) { |
| setServerPublishState(IServer.PUBLISH_STATE_NONE); |
| setServerStatus(null); |
| } else { |
| setServerPublishState(IServer.PUBLISH_STATE_UNKNOWN); |
| setServerStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Error publishing one or more modules to server")); |
| } |
| |
| GeronimoConnectionFactory.getInstance().destroy(getServer()); |
| |
| Trace.tracePoint("Exit ", Activator.traceCore, "GeronimoServerBehaviourDelegate.publishFinish"); |
| } |
| |
| |
| /** |
| * Initializes the Geronimo server delegate. This method is called by the server core framework |
| * to give delegates a chance to do their own initialization. As such, the GEP proper should |
| * never call this method. |
| * |
| * @param monitor a progress monitor, or <code>null</code> if progress reporting and cancellation |
| * are not desired |
| */ |
| @Override |
| protected void initialize(IProgressMonitor monitor) { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.initialize", monitor); |
| |
| publishStateListener = new PublishStateListener(); |
| getServer().addServerListener(publishStateListener, ServerEvent.MODULE_CHANGE | ServerEvent.PUBLISH_STATE_CHANGE); |
| |
| defaultModuleHandler = new DefaultModuleHandler(this); |
| osgiModuleHandler = new OSGiModuleHandler(this); |
| |
| removedModuleHelper = new RemovedModuleHelper(this); |
| |
| Trace.tracePoint("Exit ", Activator.traceCore, "GeronimoServerBehaviourDelegate.initialize"); |
| } |
| |
| /* |
| * GERONIMODEVTOOLS-715: Update parent module publish state to "publish" if a child |
| * publish state was changed to "publish". This is because GEP right now is redeploying the |
| * entire application instead of the individual bundle/module that has changed. Once that is |
| * supported this listener can be removed. |
| */ |
| private class PublishStateListener implements IServerListener { |
| public void serverChanged(ServerEvent event) { |
| if (event.getPublishState() == IServer.PUBLISH_STATE_INCREMENTAL || |
| event.getPublishState() == IServer.PUBLISH_STATE_FULL) { |
| // reset server status in case it was set |
| setServerStatus(null); |
| |
| IModule[] modules = event.getModule(); |
| if (modules.length > 1) { |
| if (getServer().getServerState() == IServer.STATE_STARTED) { |
| setModulePublishState(event.getModule(), IServer.PUBLISH_STATE_NONE); |
| setModuleStatus(event.getModule(), new Status(IStatus.OK, Activator.PLUGIN_ID, Messages.moduleModified)); |
| } else { |
| setModulePublishState(event.getModule(), IServer.PUBLISH_STATE_UNKNOWN); |
| setModuleStatus(event.getModule(), null); |
| } |
| |
| IModule[] newModules = new IModule[modules.length - 1]; |
| System.arraycopy(modules, 0, newModules, 0, newModules.length); |
| |
| // update parent module publish state to "publish" |
| setModulePublishState(newModules, event.getPublishState()); |
| // reset parent module status message |
| setModuleStatus(newModules, null); |
| } |
| } |
| |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.wst.server.core.model.ServerBehaviourDelegate#dispose() |
| */ |
| public void dispose() { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.dispose"); |
| stopUpdateServerStateTask(); |
| stopSynchronizeProjectOnServerTask(); |
| if (publishStateListener != null) { |
| getServer().removeServerListener(publishStateListener); |
| } |
| Trace.tracePoint("Exit", Activator.traceCore, "GeronimoServerBehaviourDelegate.dispose"); |
| } |
| |
| public String getRuntimeClass() { |
| return "org.apache.geronimo.cli.daemon.DaemonCLI"; |
| } |
| |
| public void setServerStarted() { |
| eclipseHotSwap = isEclipseHotSwapEnabled(); |
| setServerState(IServer.STATE_STARTED); |
| GeronimoConnectionFactory.getInstance().destroy(getServer()); |
| startSynchronizeProjectOnServerTask(); |
| removedModuleHelper.clearRemoveModules(); |
| } |
| |
| public void setServerStopped() { |
| setServerState(IServer.STATE_STOPPED); |
| resetModuleState(); |
| stopSynchronizeProjectOnServerTask(); |
| if (defaultModuleHandler != null) { |
| defaultModuleHandler.serverStopped(); |
| } |
| if (osgiModuleHandler != null) { |
| osgiModuleHandler.serverStopped(); |
| } |
| GeronimoConnectionFactory.getInstance().destroy(getServer()); |
| } |
| |
| public IGeronimoServer getGeronimoServer() { |
| return (IGeronimoServer) getServer().loadAdapter(IGeronimoServer.class, null); |
| } |
| |
| protected void stopImpl() { |
| GeronimoConnectionFactory.getInstance().destroy(getServer()); |
| if (processListener != null) { |
| DebugPlugin.getDefault().removeDebugEventListener(processListener); |
| processListener = null; |
| } |
| setServerState(IServer.STATE_STOPPED); |
| resetModuleState(); |
| resetKernelConnection(); |
| } |
| |
| private void resetModuleState() { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.resetModuleState"); |
| |
| IModule[] modules = getServer().getModules(); |
| for (int i = 0; i < modules.length; i++) { |
| IModule[] module = new IModule[] { modules[i] }; |
| setModuleState(module, IServer.STATE_STOPPED); |
| } |
| |
| Trace.tracePoint("Exit ", Activator.traceCore, "GeronimoServerBehaviourDelegate.resetModuleState"); |
| } |
| |
| protected AbstractModuleHandler getModuleHandler(IModule module) { |
| return (GeronimoUtils.isBundleModule(module) || GeronimoUtils.isFragmentBundleModule(module)) ? osgiModuleHandler : defaultModuleHandler; |
| } |
| |
| protected void invokeCommand(int deltaKind, IModule module, IProgressMonitor monitor) throws CoreException { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.invokeCommand", deltaKindToString(deltaKind), module.getName()); |
| AbstractModuleHandler moduleHandler = getModuleHandler(module); |
| ClassLoader old = Thread.currentThread().getContextClassLoader(); |
| try { |
| ClassLoader cl = getContextClassLoader(); |
| if (cl != null) |
| Thread.currentThread().setContextClassLoader(cl); |
| switch (deltaKind) { |
| case ADDED: { |
| moduleHandler.doAdded(module, monitor); |
| break; |
| } |
| case CHANGED: { |
| moduleHandler.doChanged(module, monitor); |
| break; |
| } |
| case REMOVED: { |
| moduleHandler.doRemoved(module, monitor); |
| break; |
| } |
| case NO_CHANGE: { |
| moduleHandler.doNoChange(module, monitor); |
| break; |
| } |
| default: |
| throw new IllegalArgumentException(); |
| } |
| } catch (CoreException e) { |
| throw e; |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } finally { |
| Thread.currentThread().setContextClassLoader(old); |
| } |
| |
| Trace.tracePoint("Exit ", Activator.traceCore, "GeronimoServerBehaviourDelegate.invokeCommand"); |
| } |
| |
| private String getModulePublishLocation(IModule[] module) { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.getModulePublishLocation", Arrays.asList(module)); |
| |
| IModule childModule = module[module.length - 1]; |
| if (childModule.isExternal()) { |
| Trace.tracePoint("Exit", Activator.traceCore, "GeronimoServerBehaviourDelegate.getModulePublishLocation", "External module"); |
| return null; |
| } |
| |
| String publishLocation = null; |
| String contextPath = getServerDelegate().getContextPath(childModule); |
| if (contextPath != null) { |
| // web module |
| publishLocation = getWebModulePublishLocation(childModule, contextPath); |
| } else if (module.length > 1 && GeronimoUtils.isEBAModule(module[0])) { |
| // bundle module within eba |
| publishLocation = getBundleModulePublishLocation(module); |
| } else { |
| // unsupported module - no publish location |
| } |
| |
| Trace.tracePoint("Exit", Activator.traceCore, "GeronimoServerBehaviourDelegate.getModulePublishLocation", publishLocation); |
| return publishLocation; |
| } |
| |
| private String getWebModulePublishLocation(IModule webModule, String contextPath) { |
| Trace.tracePoint("Enter", Activator.traceCore, "GeronimoServerBehaviourDelegate.getWebModulePublishLocation", webModule, contextPath); |
| |
| String documentBase = getWebModuleDocumentBase(contextPath); |
| if (documentBase == null) { |
| Trace.tracePoint("Exit", Activator.traceCore, "GeronimoServerBehaviourDelegate.getWebModulePublishLocation", "Document base is not set"); |
| return null; |
| } |
| |
| File publishLocation = new File(documentBase); |
| if (!publishLocation.isAbsolute()) { |
| publishLocation = getServerResource(IGeronimoServerBehavior.VAR_CATALINA_DIR + documentBase).toFile(); |
| } |
| |
| if (publishLocation.isDirectory() ) { |
| Trace.tracePoint("Exit", Activator.traceCore, "GeronimoServerBehaviourDelegate.getWebModulePublishLocation", contextPath, documentBase, publishLocation); |
| return publishLocation.getAbsolutePath(); |
| } else { |
| Trace.tracePoint("Exit", Activator.traceCore, "GeronimoServerBehaviourDelegate.getWebModulePublishLocation", "Invalid publish location", publishLocation); |
| return null; |
| } |
| } |
| |
| private String getBundleModulePublishLocation(IModule[] module) { |
| Trace.tracePoint("Enter", Activator.traceCore, "GeronimoServerBehaviourDelegate.getBundleModulePublishLocation", Arrays.asList(module)); |
| |
| IModule ebaModule = module[0]; |
| IModule bundleModule = module[module.length - 1]; |
| |
| AbstractName ebaName = getApplicationGBeanName(ebaModule); |
| if (ebaName == null) { |
| Trace.tracePoint("Exit", Activator.traceCore, "GeronimoServerBehaviourDelegate.getBundleModulePublishLocation", "Unable to get eba name"); |
| } |
| |
| File publishLocation = null; |
| try { |
| ExtendedDeploymentManager dm = (ExtendedDeploymentManager) DeploymentCommandFactory.getDeploymentManager(getServer()); |
| |
| BundleInfo bundleInfo = AriesHelper.getBundleInfo(bundleModule.getProject()); |
| |
| publishLocation = dm.getEBAContentBundlePublishLocation(ebaName, bundleInfo.getSymbolicName(), bundleInfo.getVersion().toString()); |
| } catch (Exception e) { |
| Trace.trace(Trace.WARNING, "Error getting bundle publish location", e, Activator.traceCore); |
| } |
| |
| if (publishLocation != null && publishLocation.isDirectory()) { |
| Trace.tracePoint("Exit", Activator.traceCore, "GeronimoServerBehaviourDelegate.getBundleModulePublishLocation", publishLocation); |
| return publishLocation.getAbsolutePath(); |
| } else { |
| Trace.tracePoint("Exit", Activator.traceCore, "GeronimoServerBehaviourDelegate.getBundleModulePublishLocation", "Publish location is not available or is invalid", publishLocation); |
| return null; |
| } |
| } |
| |
| private IStatus tryFileReplace(IModule[] module, IModuleResourceDelta[] deltas) { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.tryFileReplace", Arrays.asList(module)); |
| |
| String publishLocation = getModulePublishLocation(module); |
| if (publishLocation == null) { |
| Trace.tracePoint("Exit", Activator.traceCore, "GeronimoServerBehaviourDelegate.tryFileReplace", "Publish location is not set or is invalid"); |
| return null; |
| } |
| |
| if (!canPublishDelta(deltas)) { |
| Trace.tracePoint("Exit", Activator.traceCore, "GeronimoServerBehaviourDelegate.tryFileReplace", "Some modified files cannot be replaced"); |
| return null; |
| } |
| |
| Path publishPath = new Path(publishLocation); |
| List<IStatus> statusList = new ArrayList<IStatus>(); |
| for (IModuleResourceDelta delta : deltas) { |
| DeploymentUtils.publishDelta(delta, publishPath, statusList); |
| } |
| |
| IStatus status = Status.OK_STATUS; |
| if (!statusList.isEmpty()) { |
| IStatus[] statusArray = new IStatus[statusList.size()]; |
| statusList.toArray(statusArray); |
| status = new MultiStatus(Activator.PLUGIN_ID, 0, statusArray, "", null); |
| } |
| |
| Trace.tracePoint("Exit", Activator.traceCore, "GeronimoServerBehaviourDelegate.tryFileReplace", status); |
| return status; |
| } |
| |
| private boolean canPublishDelta(IModuleResourceDelta[] deltaArray) { |
| GeronimoServerDelegate delegate = getServerDelegate(); |
| List<String> includes = delegate.getNoRedeployFilePatternsAsList(true); |
| List<String> excludes = delegate.getNoRedeployFilePatternsAsList(false); |
| for (IModuleResourceDelta delta : deltaArray) { |
| if (DeploymentUtils.isMatchingDelta(delta, includes, excludes)) { |
| // delta only contains files that can be copied / replaced - keep checking |
| } else { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| protected GeronimoRuntimeDelegate getRuntimeDelegate() { |
| GeronimoRuntimeDelegate rd = (GeronimoRuntimeDelegate) getServer().getRuntime().getAdapter(GeronimoRuntimeDelegate.class); |
| if (rd == null) |
| rd = (GeronimoRuntimeDelegate) getServer().getRuntime().loadAdapter(GeronimoRuntimeDelegate.class, new NullProgressMonitor()); |
| return rd; |
| } |
| |
| protected GeronimoServerDelegate getServerDelegate() { |
| GeronimoServerDelegate sd = (GeronimoServerDelegate) getServer().getAdapter(GeronimoServerDelegate.class); |
| if (sd == null) |
| sd = (GeronimoServerDelegate) getServer().loadAdapter(GeronimoServerDelegate.class, new NullProgressMonitor()); |
| return sd; |
| } |
| |
| protected boolean isRemote() { |
| return getServer().getServerType().supportsRemoteHosts() |
| && !SocketUtil.isLocalhost(getServer().getHost()); |
| } |
| |
| protected void setupLaunchClasspath(ILaunchConfigurationWorkingCopy wc, IVMInstall vmInstall) throws CoreException { |
| List<IRuntimeClasspathEntry> cp = new ArrayList<IRuntimeClasspathEntry>(); |
| |
| //get required jar file |
| IPath libPath = getServer().getRuntime().getLocation().append("/lib"); |
| for (String jarFile: libPath.toFile().list()){ |
| IPath serverJar = libPath.append("/"+jarFile); |
| cp.add(JavaRuntime.newArchiveRuntimeClasspathEntry(serverJar)); |
| } |
| |
| // merge existing classpath with server classpath |
| IRuntimeClasspathEntry[] existingCps = JavaRuntime.computeUnresolvedRuntimeClasspath(wc); |
| |
| for (int i = 0; i < existingCps.length; i++) { |
| Trace.trace(Trace.INFO, "Classpath entry: " + existingCps[i], Activator.traceCore); |
| if (cp.contains(existingCps[i]) == false) { |
| cp.add(existingCps[i]); |
| } |
| } |
| |
| // |
| // Add classpath entries from any selected classpath containers |
| // |
| if ( getGeronimoServer().isSelectClasspathContainers()) { |
| List<String> containers = getGeronimoServer().getClasspathContainers(); |
| for ( String containerPath : containers ) { |
| List<IClasspathEntry> cpes = ClasspathContainersHelper.queryWorkspace( containerPath ); |
| for ( IClasspathEntry cpe : cpes ) { |
| RuntimeClasspathEntry rcpe = new RuntimeClasspathEntry( cpe ); |
| Trace.trace(Trace.INFO, "Classpath entry: " + rcpe , Activator.traceCore); |
| if (cp.contains(rcpe) == false) { |
| cp.add( rcpe ); |
| } |
| } |
| } |
| } |
| |
| wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH, convertCPEntryToMemento(cp)); |
| wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, false); |
| } |
| |
| private List<String> convertCPEntryToMemento(List<IRuntimeClasspathEntry> cpEntryList) { |
| List<String> list = new ArrayList<String>(cpEntryList.size()); |
| Iterator<IRuntimeClasspathEntry> iterator = cpEntryList.iterator(); |
| while (iterator.hasNext()) { |
| IRuntimeClasspathEntry entry = iterator.next(); |
| try { |
| list.add(entry.getMemento()); |
| } catch (CoreException e) { |
| Trace.trace(Trace.ERROR, "Could not resolve classpath entry: " |
| + entry, e, Activator.logCore); |
| } |
| } |
| return list; |
| } |
| |
| public void setProcess(final IProcess newProcess) { |
| if (newProcess == null) { |
| return; |
| } |
| |
| if (processListener != null) { |
| DebugPlugin.getDefault().removeDebugEventListener(processListener); |
| } |
| |
| processListener = new IDebugEventSetListener() { |
| public void handleDebugEvents(DebugEvent[] events) { |
| if (events != null) { |
| int size = events.length; |
| for (int i = 0; i < size; i++) { |
| if (newProcess.equals(events[i].getSource()) && events[i].getKind() == DebugEvent.TERMINATE) { |
| terminate(); |
| } |
| } |
| } |
| } |
| }; |
| |
| DebugPlugin.getDefault().addDebugEventListener(processListener); |
| } |
| |
| protected void startPingThread() { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.startPingThread"); |
| |
| pingThread = new PingThread(this, getServer()); |
| pingThread.start(); |
| |
| Trace.tracePoint("Exit ", Activator.traceCore, "GeronimoServerBehaviourDelegate.startPingThread"); |
| } |
| |
| protected void stopPingThread() { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.stopPingThread"); |
| |
| if (pingThread != null) { |
| pingThread.interrupt(); |
| pingThread = null; |
| } |
| |
| Trace.tracePoint("Exit ", Activator.traceCore, "GeronimoServerBehaviourDelegate.stopPingThread"); |
| } |
| |
| protected Kernel getKernel() throws SecurityException { |
| if (kernel == null) { |
| JMXConnector connector = null; |
| try { |
| connector = getJMXConnection(); |
| kernel = new JMXKernel(connector); |
| } catch (SecurityException e) { |
| IOUtils.close(connector); |
| throw e; |
| } catch (Exception e) { |
| IOUtils.close(connector); |
| Trace.trace(Trace.INFO, "Kernel connection failed. " |
| + e.getMessage(), Activator.traceCore); |
| } |
| } |
| return kernel; |
| } |
| |
| private void stopKernel() { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.stopKernel"); |
| JMXConnector jmxConnector = null; |
| try { |
| jmxConnector = getJMXConnection(); |
| MBeanServerConnection connection = jmxConnector.getMBeanServerConnection(); |
| connection.invoke(getFrameworkMBean(connection), "stopBundle", |
| new Object[] { 0 }, new String[] { long.class.getName() }); |
| } catch (Exception e) { |
| Trace.trace(Trace.ERROR, "Error while requesting server shutdown", e, Activator.traceCore); |
| } finally { |
| IOUtils.close(jmxConnector); |
| } |
| Trace.tracePoint("Exit", Activator.traceCore, "GeronimoServerBehaviourDelegate.stopKernel"); |
| } |
| |
| public boolean isKernelAlive() { |
| try { |
| Kernel kernel = getKernel(); |
| return kernel != null && kernel.isRunning(); |
| } catch (SecurityException e) { |
| Trace.trace(Trace.ERROR, "Invalid username and/or password.", e, Activator.logCore); |
| |
| pingThread.interrupt(); |
| if (getServer().getServerState() != IServer.STATE_STOPPED) { |
| forceStopJob(true,e); |
| } |
| } catch (Exception e) { |
| Trace.trace(Trace.WARNING, "Geronimo Server may have been terminated manually outside of workspace.", e, Activator.logCore); |
| resetKernelConnection(); |
| } |
| return false; |
| } |
| |
| public void resetKernelConnection() { |
| Trace.traceEntry(Activator.traceCore, "GeronimoServerBehaviourDelegate.resetKernelConnection"); |
| JMXKernel local = kernel; |
| kernel = null; |
| IOUtils.close(local); |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.resetKernelConnection"); |
| } |
| |
| private void forceStopJob(boolean b, final SecurityException e) { |
| /* |
| * |
| * Currently, there is another Status is returned by StartJob in Server. |
| * The message doesn't contain reason for the exception. |
| * So this job is created to show a message(Invalid username and/or password) to user. |
| * |
| * TODO: Need a method to remove the error message thrown by StartJob in Server. |
| * |
| */ |
| |
| String jobName = NLS.bind(org.eclipse.wst.server.core.internal.Messages.errorStartFailed, getServer().getName()); |
| |
| //This message has different variable names in WTP 3.0 and 3.1, so we define it here instead of using that in WTP |
| final String jobStartingName = NLS.bind("Starting {0}", getServer().getName()); |
| |
| new Job(jobName) { |
| @Override |
| protected IStatus run(IProgressMonitor monitor) { |
| MultiStatus multiStatus = new MultiStatus(Activator.PLUGIN_ID, 0, jobStartingName, null); |
| multiStatus.add(new Status(IStatus.ERROR,Activator.PLUGIN_ID,0,"Invalid username and/or password.",e)); |
| try { |
| stop(true); |
| } catch (Exception e){ |
| multiStatus.add(new Status(IStatus.ERROR,Activator.PLUGIN_ID,0,"Failed to stop server",e)); |
| } |
| |
| return multiStatus; |
| } |
| }.schedule(); |
| |
| } |
| |
| public boolean isFullyStarted() { |
| if (isKernelAlive()) { |
| AbstractNameQuery query = new AbstractNameQuery(PersistentConfigurationList.class.getName()); |
| Set<AbstractName> configLists = kernel.listGBeans(query); |
| if (!configLists.isEmpty()) { |
| AbstractName on = (AbstractName) configLists.toArray()[0]; |
| try { |
| Boolean b = (Boolean) kernel.getAttribute(on, "kernelFullyStarted"); |
| return b.booleanValue(); |
| } catch (GBeanNotFoundException e) { |
| // ignore |
| } catch (NoSuchAttributeException e) { |
| // ignore |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } else { |
| Trace.trace(Trace.INFO, "configLists is empty", Activator.traceCore); |
| } |
| } |
| return false; |
| } |
| |
| |
| @Override |
| public IPath getServerResource(String path) { |
| IPath serverRoot = getServer().getRuntime().getLocation(); |
| return serverRoot.append(path); |
| } |
| |
| public void startUpdateServerStateTask() { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.startUpdateServerStateTask", getServer().getName()); |
| |
| stateTimer = new Timer(true); |
| stateTimer.schedule(new UpdateServerStateTask(this, getServer()), 0, TIMER_TASK_INTERVAL * 1000); |
| |
| Trace.tracePoint("Exit ", Activator.traceCore, "GeronimoServerBehaviourDelegate.startUpdateServerStateTask"); |
| } |
| |
| public void startSynchronizeProjectOnServerTask() { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.startSynchronizeProjectOnServerTask", getServer().getName()); |
| |
| if (synchronizerTask != null) { |
| synchronizerTask.stop(); |
| } |
| |
| synchronizerTask = new SynchronizeProjectOnServerTask(this, getServer()); |
| synchronizerTask.start(); |
| |
| Trace.tracePoint("Exit ", Activator.traceCore, "GeronimoServerBehaviourDelegate.startSynchronizeProjectOnServerTask"); |
| } |
| |
| public void stopUpdateServerStateTask() { |
| Trace.tracePoint("Entry", "GeronimoServerBehaviourDelegate.stopUpdateServerStateTask", Activator.traceCore); |
| |
| if (stateTimer != null) { |
| stateTimer.cancel(); |
| stateTimer = null; |
| } |
| |
| Trace.tracePoint("Exit ", "GeronimoServerBehaviourDelegate.stopUpdateServerStateTask", Activator.traceCore); |
| } |
| |
| public void stopSynchronizeProjectOnServerTask() { |
| Trace.tracePoint("Entry", "GeronimoServerBehaviourDelegate.stopSynchronizeProjectOnServerTask", Activator.traceCore); |
| |
| if (synchronizerTask != null) { |
| synchronizerTask.stop(); |
| synchronizerTask = null; |
| } |
| |
| Trace.tracePoint("Exit ", "GeronimoServerBehaviourDelegate.stopSynchronizeProjectOnServerTask", Activator.traceCore); |
| } |
| |
| protected IPath getModulePath(IModule[] module, URL baseURL) { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.getModulePath", Arrays.asList(module), baseURL); |
| |
| IPath modulePath = new Path(baseURL.getFile()); |
| |
| if (module.length == 2) { |
| IModule workingModule = module[module.length - 1]; |
| modulePath = modulePath.append(workingModule.getName()); |
| if (GeronimoUtils.isWebModule(workingModule)) { |
| modulePath = modulePath.addFileExtension("war"); |
| } else if (GeronimoUtils.isEjbJarModule(workingModule)) { |
| modulePath = modulePath.addFileExtension("jar"); |
| } else if (GeronimoUtils.isRARModule(workingModule)) { |
| modulePath = modulePath.addFileExtension("rar"); |
| } else if (GeronimoUtils.isEarModule(workingModule)) { |
| modulePath = modulePath.addFileExtension("ear"); |
| } else if (GeronimoUtils.isAppClientModule(workingModule)) { |
| modulePath = modulePath.addFileExtension("jar"); |
| } |
| } |
| |
| Trace.tracePoint("Exit ", Activator.traceCore, "GeronimoServerBehaviourDelegate.getModulePath", modulePath); |
| return modulePath; |
| } |
| |
| private Kernel getDeploymentManagerKernel() { |
| GeronimoConnectionFactory connectionFactory = GeronimoConnectionFactory.getInstance(); |
| try { |
| JMXDeploymentManager manager = |
| (JMXDeploymentManager) connectionFactory.getDeploymentManager(getServer()); |
| return manager.getKernel(); |
| } catch (DeploymentManagerCreationException e) { |
| Trace.trace(Trace.WARNING, "Error getting kernel from deployment manager", e, Activator.logCore); |
| return null; |
| } |
| } |
| |
| public JMXConnector getJMXConnection() throws Exception { |
| GeronimoServerDelegate delegate = getServerDelegate(); |
| |
| String host = delegate.getServer().getHost(); |
| String user = delegate.getAdminID(); |
| String password = delegate.getAdminPassword(); |
| String port = String.valueOf(delegate.getActualRMINamingPort()); |
| JMXConnectorInfo connectorInfo = new JMXConnectorInfo(user, password, host, port); |
| |
| // Using the classloader that loads the current's class as the default classloader when creating the JMXConnector |
| JMXConnector jmxConnector = GeronimoJMXConnectorFactory.create(connectorInfo, this.getClass().getClassLoader()); |
| |
| return jmxConnector; |
| } |
| |
| /* XXX: Should be avoided as there is no explicit way to close the connection */ |
| public MBeanServerConnection getServerConnection() throws Exception { |
| return getJMXConnection().getMBeanServerConnection(); |
| } |
| |
| public ObjectName getMBean(MBeanServerConnection connection, String mbeanName, String name) throws Exception { |
| Set<ObjectName> objectNameSet = |
| connection.queryNames(new ObjectName(mbeanName), null); |
| if (objectNameSet.isEmpty()) { |
| throw new Exception(Messages.bind(Messages.mBeanNotFound, name)); |
| } else if (objectNameSet.size() == 1) { |
| return objectNameSet.iterator().next(); |
| } else { |
| throw new Exception(Messages.bind(Messages.multipleMBeansFound, name)); |
| } |
| } |
| |
| private ObjectName getFrameworkMBean(MBeanServerConnection connection) throws Exception { |
| return getMBean(connection, "osgi.core:type=framework,*", "Framework"); |
| } |
| |
| private void invokeGC() { |
| Trace.traceEntry(Activator.traceCore, "GeronimoServerBehaviourDelegate.invokeGC"); |
| JMXConnector jmxConnector = null; |
| try { |
| jmxConnector = getJMXConnection(); |
| MBeanServerConnection connection = jmxConnector.getMBeanServerConnection(); |
| ObjectName name = getMBean(connection, "java.lang:type=Memory", "Memory"); |
| connection.invoke(name, "gc", new Object [0], new String [0]); |
| } catch (Exception e) { |
| Trace.trace(Trace.ERROR, "Error while requesting server gc", e, Activator.traceCore); |
| } finally { |
| IOUtils.close(jmxConnector); |
| } |
| Trace.traceExit(Activator.traceCore, "GeronimoServerBehaviourDelegate.invokeGC"); |
| } |
| |
| public Target[] getTargets() { |
| return null; |
| } |
| |
| public static String deltaKindToString(int kind) { |
| switch(kind) { |
| case NO_CHANGE: |
| return "NO_CHANGE"; |
| case ADDED: |
| return "ADDED"; |
| case CHANGED: |
| return "CHANGED"; |
| case REMOVED: |
| return "REMOVED"; |
| } |
| return Integer.toString(kind); |
| } |
| |
| public static String publishKindToString(int kind) { |
| switch(kind) { |
| case IServer.PUBLISH_AUTO: |
| return "Auto"; |
| case IServer.PUBLISH_CLEAN: |
| return "Clean"; |
| case IServer.PUBLISH_FULL: |
| return "Full"; |
| case IServer.PUBLISH_INCREMENTAL: |
| return "Incremental"; |
| } |
| return Integer.toString(kind); |
| } |
| |
| public static void traceModuleResourceDelta(IModuleResourceDelta[] deltaArray, String tab) { |
| if (deltaArray != null) { |
| for (IModuleResourceDelta delta : deltaArray) { |
| int kind = delta.getKind(); |
| IModuleResource resource = delta.getModuleResource(); |
| Trace.trace(Trace.INFO, tab + resource.getName() + " " + deltaKindToString(kind), Activator.traceCore); |
| if (resource instanceof IModuleFile) { |
| // ignore |
| } else if (resource instanceof IModuleFolder) { |
| IModuleResourceDelta[] childDeltaArray = delta.getAffectedChildren(); |
| traceModuleResourceDelta(childDeltaArray, tab + " "); |
| } |
| } |
| } |
| } |
| |
| public String getConfigId(IModule module) throws Exception { |
| return getGeronimoServer().getVersionHandler().getConfigID(module); |
| } |
| |
| private IStatus updateSharedLib(IModule[] module, IProgressMonitor monitor) { |
| IDataModel model = DataModelFactory.createDataModel(new SharedLibEntryDataModelProvider()); |
| model.setProperty(ISharedLibEntryCreationDataModelProperties.MODULES, module); |
| model.setProperty(ISharedLibEntryCreationDataModelProperties.SERVER, getServer()); |
| IDataModelOperation op = new SharedLibEntryCreationOperation(model); |
| try { |
| op.execute(monitor, null); |
| } catch (ExecutionException e) { |
| return new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, e.getMessage(), e.getCause()); |
| } |
| return Status.OK_STATUS; |
| } |
| |
| @Override |
| public void startModule(IModule[] module, IProgressMonitor monitor) { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.startModule", Arrays.asList(module)); |
| try { |
| getModuleHandler(module[0]).doStartModule(module, monitor); |
| } catch (Exception e) { |
| Trace.trace(Trace.ERROR, "Error starting module " + module[0].getName(), e, Activator.logCore); |
| throw new RuntimeException("Error starting module " + module[0].getName(), e); |
| } |
| Trace.tracePoint("Exit ", Activator.traceCore, "GeronimoServerBehaviourDelegate.startModule"); |
| } |
| |
| @Override |
| public void stopModule(IModule[] module, IProgressMonitor monitor) { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.stopModule", Arrays.asList(module)); |
| try { |
| getModuleHandler(module[0]).doStopModule(module, monitor); |
| } catch (Exception e) { |
| Trace.trace(Trace.ERROR, "Error stopping module " + module[0].getName(), e, Activator.logCore); |
| throw new RuntimeException("Error stopping module " + module[0].getName(), e); |
| } |
| Trace.tracePoint("Exit ", Activator.traceCore, "GeronimoServerBehaviourDelegate.stopModule"); |
| } |
| |
| @Override |
| public void restartModule(IModule[] module, IProgressMonitor monitor) { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.restartModule", Arrays.asList(module)); |
| try { |
| getModuleHandler(module[0]).doRestartModule(module, monitor); |
| } catch (Exception e) { |
| Trace.trace(Trace.ERROR, "Error restarting module " + module[0].getName(), e, Activator.logCore); |
| throw new RuntimeException("Error restarting module " + module[0].getName(), e); |
| } |
| Trace.tracePoint("Exit ", Activator.traceCore, "GeronimoServerBehaviourDelegate.restartModule"); |
| } |
| |
| @Override |
| public boolean canControlModule(IModule[] module) { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.canControlModule", Arrays.asList(module)); |
| // Enable start/stop for top-level modules only |
| if (module.length == 1) { |
| if (GeronimoUtils.isFragmentBundleModule(module[0])) { |
| // fragment bundles cannot be started/stopped |
| return false; |
| } else { |
| return true; |
| } |
| } else { |
| return false; |
| } |
| } |
| |
| public void setModulesState(IModule[] module, int state) { |
| setModuleState(module, state); |
| } |
| |
| public IPath getPublishDirectory(IModule[] module) { |
| if (module == null || module.length == 0) |
| return null; |
| |
| if (getGeronimoServer().isRunFromWorkspace()) { |
| // TODO fix me, see if project root, component root, or output |
| // container should be returned |
| return module[module.length - 1].getProject().getLocation(); |
| } else { |
| ClassLoader old = Thread.currentThread().getContextClassLoader(); |
| try { |
| Thread.currentThread().setContextClassLoader(getContextClassLoader()); |
| String configId = getConfigId(module[0]); |
| Artifact artifact = Artifact.create(configId); |
| AbstractName name = Configuration.getConfigurationAbstractName(artifact); |
| GBeanData data = kernel.getGBeanData(name); |
| URL url = (URL) data.getAttribute("baseURL"); |
| return getModulePath(module, url); |
| } catch (InvalidConfigException e) { |
| e.printStackTrace(); |
| } catch (GBeanNotFoundException e) { |
| e.printStackTrace(); |
| } catch (InternalKernelException e) { |
| e.printStackTrace(); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } finally { |
| Thread.currentThread().setContextClassLoader(old); |
| } |
| } |
| |
| return null; |
| } |
| |
| // TODO: this can be cached |
| public String getWebModuleDocumentBase(String contextPath) { |
| Kernel kernel = getDeploymentManagerKernel(); |
| if (kernel == null) { |
| Trace.trace(Trace.WARNING, "Error getting web module document base - no kernel", null, Activator.logCore); |
| return null; |
| } |
| Map<String, String> map = Collections.singletonMap("j2eeType", "WebModule"); |
| if (!contextPath.startsWith("/")) { |
| contextPath = "/" + contextPath; |
| } |
| AbstractNameQuery query = new AbstractNameQuery(null, map, Collections.EMPTY_SET); |
| Set<AbstractName> webModuleNames = kernel.listGBeans(query); |
| for (AbstractName name : webModuleNames) { |
| try { |
| String moduleContextPath = (String) kernel.getAttribute(name, "contextPath"); |
| if (contextPath.equals(moduleContextPath)) { |
| String docBase = (String) kernel.getAttribute(name, "docBase"); |
| return (docBase != null && docBase.length() > 0) ? docBase : null; |
| } |
| } catch (GBeanNotFoundException e) { |
| // ignore |
| } catch (NoSuchAttributeException e) { |
| // ignore |
| } catch (Exception e) { |
| Trace.trace(Trace.WARNING, "Error getting web module document base", e, Activator.logCore); |
| } |
| } |
| return null; |
| } |
| |
| public OSGiModuleHandler getOsgiModuleHandler() { |
| return osgiModuleHandler; |
| } |
| |
| public boolean isPublished(IModule[] module) { |
| return super.hasBeenPublished(module); |
| } |
| |
| public boolean hasChanged(IModule rootModule) { |
| IModule[] module = new IModule [] { rootModule }; |
| IModuleResourceDelta[] deltaArray = getPublishedResourceDelta(module); |
| if (deltaArray != null && deltaArray.length > 0) { |
| return true; |
| } |
| IModule[] childModules = getServerDelegate().getChildModules(module); |
| if (childModules != null) { |
| for (IModule childModule : childModules) { |
| deltaArray = getPublishedResourceDelta(new IModule[] {rootModule, childModule}); |
| if (deltaArray != null && deltaArray.length > 0) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| public Set<String> getModifiedConfigIds() { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.getModifiedConfigIds"); |
| |
| IServer server = getServer(); |
| Set<String> configIds = new HashSet<String>(); |
| IModule[] modules = server.getModules(); |
| if (modules != null) { |
| for (IModule module : modules) { |
| IModule[] rootModule = new IModule[] { module }; |
| // only consider modules that have been published and have changed |
| if (isPublished(rootModule) && hasChanged(module)) { |
| try { |
| String configId = DeploymentUtils.getConfigId(server, module); |
| configIds.add(configId); |
| } catch (CoreException e) { |
| // ignore |
| } |
| } |
| } |
| } |
| |
| Trace.tracePoint("Exit", Activator.traceCore, "GeronimoServerBehaviourDelegate.getModifiedConfigIds", configIds); |
| return configIds; |
| } |
| |
| public Set<String> getDeletedConfigIds() { |
| Trace.tracePoint("Entry", Activator.traceCore, "GeronimoServerBehaviourDelegate.getDeletedConfigIds"); |
| Set<String> configIds = removedModuleHelper.getRemovedConfigIds(); |
| Trace.tracePoint("Exit", Activator.traceCore, "GeronimoServerBehaviourDelegate.getDeletedConfigIds", configIds); |
| return configIds; |
| } |
| |
| protected RemovedModuleHelper getRemovedModuleHelper() { |
| return removedModuleHelper; |
| } |
| |
| } |