PageRenderTime 907ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/projects/netbeans-7.3/j2eeserver/src/org/netbeans/modules/j2ee/deployment/impl/ServerInstance.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 1262 lines | 911 code | 124 blank | 227 comment | 214 complexity | 7482f1add1d579b0eeaf4e4d54ff2790 MD5 | raw file
  1. /*
  2. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  3. *
  4. * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
  5. *
  6. * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  7. * Other names may be trademarks of their respective owners.
  8. *
  9. * The contents of this file are subject to the terms of either the GNU
  10. * General Public License Version 2 only ("GPL") or the Common
  11. * Development and Distribution License("CDDL") (collectively, the
  12. * "License"). You may not use this file except in compliance with the
  13. * License. You can obtain a copy of the License at
  14. * http://www.netbeans.org/cddl-gplv2.html
  15. * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  16. * specific language governing permissions and limitations under the
  17. * License. When distributing the software, include this License Header
  18. * Notice in each file and include the License file at
  19. * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
  20. * particular file as subject to the "Classpath" exception as provided
  21. * by Oracle in the GPL Version 2 section of the License file that
  22. * accompanied this code. If applicable, add the following below the
  23. * License Header, with the fields enclosed by brackets [] replaced by
  24. * your own identifying information:
  25. * "Portions Copyrighted [year] [name of copyright owner]"
  26. *
  27. * Contributor(s):
  28. *
  29. * The Original Software is NetBeans. The Initial Developer of the Original
  30. * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
  31. * Microsystems, Inc. All Rights Reserved.
  32. *
  33. * If you wish your version of this file to be governed by only the CDDL
  34. * or only the GPL Version 2, indicate your decision by adding
  35. * "[Contributor] elects to include this software in this distribution
  36. * under the [CDDL or GPL Version 2] license." If you do not indicate a
  37. * single choice of license, a recipient has the option to distribute
  38. * your version of this file under either the CDDL, the GPL Version 2 or
  39. * to extend the choice of license to its licensees as provided above.
  40. * However, if you add GPL Version 2 code and therefore, elected the GPL
  41. * Version 2 license, then the option applies only if the new code is
  42. * made subject to such option by the copyright holder.
  43. */
  44. package org.netbeans.modules.j2ee.deployment.impl;
  45. import java.beans.PropertyChangeEvent;
  46. import java.beans.PropertyChangeListener;
  47. import java.net.InetAddress;
  48. import java.net.NetworkInterface;
  49. import java.net.SocketException;
  50. import java.net.UnknownHostException;
  51. import javax.enterprise.deploy.spi.*;
  52. import javax.enterprise.deploy.shared.*;
  53. import org.netbeans.modules.j2ee.deployment.common.api.ConfigurationException;
  54. import javax.enterprise.deploy.spi.status.*;
  55. import javax.swing.JButton;
  56. import javax.swing.SwingUtilities;
  57. import org.netbeans.api.debugger.DebuggerManager;
  58. import org.netbeans.api.debugger.DebuggerManagerAdapter;
  59. import org.netbeans.api.debugger.Session;
  60. import org.netbeans.api.debugger.jpda.AttachingDICookie;
  61. import org.netbeans.api.debugger.jpda.JPDADebugger;
  62. import org.netbeans.modules.j2ee.deployment.common.api.Datasource;
  63. import org.netbeans.modules.j2ee.deployment.common.api.DatasourceAlreadyExistsException;
  64. import org.netbeans.modules.j2ee.deployment.devmodules.spi.ArtifactListener.Artifact;
  65. import org.netbeans.modules.j2ee.deployment.plugins.spi.JDBCDriverDeployer;
  66. import java.util.*;
  67. import java.util.concurrent.CopyOnWriteArrayList;
  68. import java.util.concurrent.Executors;
  69. import java.util.concurrent.ScheduledExecutorService;
  70. import java.util.concurrent.TimeUnit;
  71. import java.util.concurrent.TimeoutException;
  72. import java.util.concurrent.atomic.AtomicReference;
  73. import java.util.logging.Level;
  74. import java.util.logging.Logger;
  75. import javax.enterprise.deploy.spi.exceptions.DeploymentManagerCreationException;
  76. import javax.swing.event.ChangeListener;
  77. import org.netbeans.api.annotations.common.NonNull;
  78. import org.netbeans.api.debugger.LazyDebuggerManagerListener;
  79. import org.netbeans.modules.j2ee.deployment.common.api.MessageDestination;
  80. import org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment;
  81. import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
  82. import org.netbeans.modules.j2ee.deployment.impl.ui.ProgressUI;
  83. import org.netbeans.modules.j2ee.deployment.plugins.api.InstanceProperties;
  84. import org.netbeans.modules.j2ee.deployment.plugins.spi.J2eePlatformImpl;
  85. import org.netbeans.modules.j2ee.deployment.plugins.api.ServerDebugInfo;
  86. import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibrary;
  87. import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibraryDependency;
  88. import org.netbeans.modules.j2ee.deployment.plugins.spi.StartServer;
  89. import org.netbeans.modules.j2ee.deployment.plugins.spi.TargetModuleIDResolver;
  90. import org.netbeans.modules.j2ee.deployment.plugins.api.UISupport;
  91. import org.netbeans.modules.j2ee.deployment.plugins.spi.AntDeploymentProvider;
  92. import org.netbeans.modules.j2ee.deployment.plugins.spi.DatasourceManager;
  93. import org.netbeans.modules.j2ee.deployment.plugins.spi.FindJSPServlet;
  94. import org.netbeans.modules.j2ee.deployment.plugins.spi.IncrementalDeployment;
  95. import org.netbeans.modules.j2ee.deployment.plugins.spi.J2eePlatformFactory;
  96. import org.netbeans.modules.j2ee.deployment.plugins.spi.MessageDestinationDeployment;
  97. import org.netbeans.modules.j2ee.deployment.plugins.spi.ServerInstanceDescriptor;
  98. import org.netbeans.modules.j2ee.deployment.plugins.spi.ServerLibraryManager;
  99. import org.netbeans.modules.j2ee.deployment.profiler.api.ProfilerSupport;
  100. import org.netbeans.modules.j2ee.deployment.profiler.spi.Profiler;
  101. import org.openide.nodes.Node;
  102. import org.openide.util.NbBundle;
  103. import org.openide.NotifyDescriptor;
  104. import org.openide.DialogDisplayer;
  105. import org.openide.util.ChangeSupport;
  106. import org.openide.util.Exceptions;
  107. import org.openide.util.Parameters;
  108. import org.openide.util.RequestProcessor;
  109. import org.openide.util.WeakListeners;
  110. import org.openide.windows.InputOutput;
  111. public class ServerInstance implements Node.Cookie, Comparable {
  112. /** Server state is being checked or state changes is in progress */
  113. public static final int STATE_WAITING = 1;
  114. /** Server is stopped */
  115. public static final int STATE_STOPPED = 2;
  116. /** Server is running in normal mode */
  117. public static final int STATE_RUNNING = 3;
  118. /** Server is running in debug mode */
  119. public static final int STATE_DEBUGGING = 4;
  120. /** Server is suspended on a break point (in debug mode and not responding) */
  121. public static final int STATE_SUSPENDED = 5;
  122. /** Server is running in profile mode */
  123. public static final int STATE_PROFILING = 6;
  124. /** Server is ready for the profiler to connect, server JVM is blocked. */
  125. public static final int STATE_PROFILER_BLOCKING = 7;
  126. /** Server is starting in profile mode. */
  127. public static final int STATE_PROFILER_STARTING = 8;
  128. /** For how long should plugins be allowed to block in the isRunning method */
  129. private static final int RUNNING_CHECK_TIMEOUT = 10000; // in millis
  130. /** For how long should plugins be allowed to block in the isDebuggable method */
  131. private static final int DEBUGGING_CHECK_TIMEOUT = 10000; // in millis
  132. /** Default maximum amount of time the server should finish starting/stopping/deploying in */
  133. private static final long DEFAULT_TIMEOUT = 1200000; // in millis
  134. private static final Logger LOGGER = Logger.getLogger(ServerInstance.class.getName());
  135. private static final RequestProcessor REFRESH_PROCESSOR =
  136. new RequestProcessor("Java EE server registry refresh", 5);
  137. private static final RequestProcessor DEBUGGER_STATE_PROCESSOR =
  138. new RequestProcessor("Java EE server debugger state", 1);
  139. private final String url;
  140. private final Server server;
  141. private final boolean nonPeristent;
  142. private DeploymentManager manager;
  143. private DeploymentManager disconnectedManager;
  144. private IncrementalDeployment incrementalDeployment;
  145. private ServerInstanceDescriptor instanceDescriptor;
  146. private TargetModuleIDResolver tmidResolver;
  147. private J2eePlatform j2eePlatform;
  148. private J2eePlatformImpl j2eePlatformImpl;
  149. private StartServer startServer;
  150. private FindJSPServlet findJSPServlet;
  151. private ServerLibraryManager libraryManager;
  152. private ServerLibraryManager disconnectedLibraryManager;
  153. private DatasourceManager dsMgr;
  154. private DatasourceManager ddsMgr;
  155. private MessageDestinationDeployment msgDestDeploymentConnected;
  156. private MessageDestinationDeployment msgDestDeploymentDisconnected;
  157. private final Set targetsStartedByIde = new HashSet(); // valued by target name
  158. private Map targets; // keyed by target name, valued by ServerTarget
  159. private boolean managerStartedByIde = false;
  160. private ServerTarget coTarget = null;
  161. private final DeletableInstanceProperties instanceProperties;
  162. private final HashMap/*<Target, ServerDebugInfo>*/ debugInfo = new HashMap();
  163. // last known server state, the initial value is stopped
  164. private volatile int serverState = STATE_STOPPED;
  165. // server state listeners
  166. private final List<StateListener> stateListeners = new CopyOnWriteArrayList<StateListener>();
  167. // running check helpers
  168. private long lastCheck = 0;
  169. private boolean isRunning = false;
  170. private final ChangeSupport managerChangeSupport = new ChangeSupport(this);
  171. private static AtomicReference<ServerInstance> profiledServerInstance = new AtomicReference<ServerInstance>();
  172. private final DebuggerStateListener debuggerStateListener;
  173. // PENDING how to manage connected/disconnected servers with the same manager?
  174. // maybe concept of 'default unconnected instance' is broken?
  175. public ServerInstance(Server server, String url, boolean nonPersistent) {
  176. this.server = server;
  177. this.url = url;
  178. this.nonPeristent = nonPersistent;
  179. instanceProperties = nonPersistent ? new MemoryInstancePropertiesImpl(url)
  180. : new DefaultInstancePropertiesImpl(url);
  181. // listen to debugger changes so that we can update server status accordingly
  182. debuggerStateListener = new DebuggerStateListener();
  183. DebuggerManager.getDebuggerManager().addDebuggerListener(
  184. WeakListeners.create(LazyDebuggerManagerListener.class, debuggerStateListener,
  185. DebuggerManager.getDebuggerManager()));
  186. }
  187. /** Return this server instance InstanceProperties. */
  188. public InstanceProperties getInstanceProperties() {
  189. return instanceProperties;
  190. }
  191. /** Return display name of this server instance.*/
  192. public String getDisplayName() {
  193. return instanceProperties.getProperty(InstanceProperties.DISPLAY_NAME_ATTR);
  194. }
  195. public void addManagerChangeListener(ChangeListener listener) {
  196. managerChangeSupport.addChangeListener(listener);
  197. }
  198. public void removeManagerChangeListener(ChangeListener listener) {
  199. managerChangeSupport.removeChangeListener(listener);
  200. }
  201. /**
  202. * Returns value of the specified timeout propety in milliseconds. If the
  203. * timeout property is not defined the specified default values is returned.
  204. *
  205. * @param propName timeout property
  206. * @param defaultValue value which will be returned when the specified timeout
  207. * property is not set.
  208. *
  209. * @return value of the specified timeout propety in milliseconds.
  210. */
  211. private long getTimeout(String propName, long defaultValue) {
  212. long returnValue = defaultValue;
  213. String timeout = instanceProperties.getProperty(propName);
  214. if (timeout != null) {
  215. try {
  216. returnValue = Long.parseLong(timeout) * 1000;
  217. } catch (NumberFormatException e) {
  218. LOGGER.log(Level.FINE, "could not parse timeout property", e); // NOI18N
  219. }
  220. }
  221. return returnValue;
  222. }
  223. /** Get the server startup timeout in milliseconds */
  224. private long getStartupTimeout() {
  225. return getTimeout(InstanceProperties.STARTUP_TIMEOUT, DEFAULT_TIMEOUT);
  226. }
  227. /** Get the server shutdown timeout in milliseconds */
  228. private long getShutdownTimeout() {
  229. return getTimeout(InstanceProperties.SHUTDOWN_TIMEOUT, DEFAULT_TIMEOUT);
  230. }
  231. /** Get the deployment timeout in milliseconds */
  232. long getDeploymentTimeout() {
  233. return getTimeout(InstanceProperties.DEPLOYMENT_TIMEOUT, DEFAULT_TIMEOUT);
  234. }
  235. public Server getServer() {
  236. return server;
  237. }
  238. public String getUrl() {
  239. return url;
  240. }
  241. public DeploymentManager getDeploymentManager() {
  242. DeploymentManager managerTmp = null;
  243. synchronized (this) {
  244. managerTmp = manager;
  245. }
  246. if (managerTmp != null) {
  247. return managerTmp;
  248. }
  249. try {
  250. if (instanceProperties.isDeleted()) {
  251. String msg = NbBundle.getMessage(ServerInstance.class, "MSG_InstanceNotExists", url);
  252. throw new IllegalStateException(msg);
  253. }
  254. String username = instanceProperties.getProperty(InstanceProperties.USERNAME_ATTR);
  255. String password;
  256. if (nonPeristent) {
  257. password = instanceProperties.getProperty(InstanceProperties.PASSWORD_ATTR);
  258. } else {
  259. password = ServerRegistry.readPassword(url);
  260. }
  261. managerTmp = server.getDeploymentManager(url, username, password);
  262. boolean fire = false;
  263. synchronized (this) {
  264. fire = (manager != managerTmp);
  265. manager = managerTmp;
  266. }
  267. if (fire) {
  268. firePossibleManagerChange();
  269. }
  270. } catch(javax.enterprise.deploy.spi.exceptions.DeploymentManagerCreationException e) {
  271. throw new RuntimeException(e);
  272. }
  273. return managerTmp;
  274. }
  275. public synchronized boolean isConnected () {
  276. return manager != null;
  277. }
  278. public DeploymentManager getDisconnectedDeploymentManager() throws DeploymentManagerCreationException {
  279. DeploymentManager disconnectedManagerTmp = null;
  280. synchronized (this) {
  281. disconnectedManagerTmp = disconnectedManager;
  282. }
  283. if (disconnectedManagerTmp != null) {
  284. return disconnectedManagerTmp;
  285. }
  286. if (instanceProperties.isDeleted()) {
  287. String msg = NbBundle.getMessage(ServerInstance.class, "MSG_InstanceNotExists", url);
  288. throw new DeploymentManagerCreationException(msg);
  289. }
  290. disconnectedManagerTmp = server.getDisconnectedDeploymentManager(url);
  291. boolean fire = false;
  292. synchronized (this) {
  293. fire = (manager == null) && (disconnectedManager != disconnectedManagerTmp);
  294. disconnectedManager = disconnectedManagerTmp;
  295. }
  296. if (fire) {
  297. firePossibleManagerChange();
  298. }
  299. return disconnectedManagerTmp;
  300. }
  301. public J2eePlatform getJ2eePlatform() {
  302. return j2eePlatform;
  303. }
  304. public void setJ2eePlatform(J2eePlatform aJ2eePlatform ) {
  305. j2eePlatform = aJ2eePlatform;
  306. }
  307. public J2eePlatformImpl getJ2eePlatformImpl() {
  308. if (j2eePlatformImpl == null) {
  309. J2eePlatformFactory fact = server.getJ2eePlatformFactory();
  310. // TODO this will be removed, implementation of J2EEPlatformFactory will be mandatory
  311. if (fact != null) {
  312. try {
  313. j2eePlatformImpl = fact.getJ2eePlatformImpl(isConnected() ? getDeploymentManager() : getDisconnectedDeploymentManager());
  314. } catch (DeploymentManagerCreationException dmce) {
  315. // this condition is ugly workaround for disconnected
  316. // deployment manager throwing exception - bug 113907
  317. if (!instanceProperties.isDeleted()) {
  318. Exceptions.printStackTrace(dmce);
  319. }
  320. }
  321. }
  322. }
  323. return j2eePlatformImpl;
  324. }
  325. public ServerDebugInfo getServerDebugInfo(Target target) {
  326. assert debugInfo != null;
  327. ServerDebugInfo sdi = null;
  328. if (target == null) { //performance: treat as special simple case
  329. sdi = (ServerDebugInfo) debugInfo.get(null);
  330. } else {
  331. for (Iterator it = debugInfo.keySet().iterator(); sdi == null && it.hasNext(); ) {
  332. Target t = (Target) it.next();
  333. if (t == target || (t != null && t.getName().equals(target.getName()))) {
  334. sdi = (ServerDebugInfo) debugInfo.get(t);
  335. }
  336. }
  337. }
  338. return sdi;
  339. }
  340. public void refresh() {
  341. REFRESH_PROCESSOR.post(new Runnable() {
  342. @Override
  343. public void run() {
  344. try {
  345. int oldState = getServerState();
  346. setServerState(STATE_WAITING);
  347. if (ServerInstance.this == profiledServerInstance.get()) {
  348. updateStateFromProfiler();
  349. return;
  350. }
  351. if (isSuspended()) {
  352. setServerState(ServerInstance.STATE_SUSPENDED);
  353. } else if (isDebuggable(null)) {
  354. if (oldState != ServerInstance.STATE_SUSPENDED) {
  355. // this will decrease the possibility of accessing server
  356. // when it is in suspended mode when we might freeze
  357. reset();
  358. }
  359. initCoTarget();
  360. setServerState(ServerInstance.STATE_DEBUGGING);
  361. } else if (isReallyRunning()) {
  362. reset();
  363. initCoTarget();
  364. setServerState(ServerInstance.STATE_RUNNING);
  365. } else {
  366. reset();
  367. setServerState(ServerInstance.STATE_STOPPED);
  368. }
  369. } finally {
  370. // safety catch - make sure that we are not still waiting
  371. if (getServerState() == STATE_WAITING) {
  372. setServerState(ServerInstance.STATE_STOPPED);
  373. }
  374. }
  375. }
  376. });
  377. }
  378. public void reset() {
  379. DeploymentManager managerTmp = null;
  380. synchronized (this) {
  381. managerTmp = manager;
  382. manager = null;
  383. disconnectedManager = null;
  384. incrementalDeployment = null;
  385. tmidResolver = null;
  386. startServer = null;
  387. findJSPServlet = null;
  388. coTarget = null;
  389. targets = null;
  390. }
  391. firePossibleManagerChange();
  392. if (managerTmp != null) {
  393. managerTmp.release();
  394. }
  395. }
  396. /** Remove this server instance and stop it if it has been started from within the IDE */
  397. public void remove() {
  398. DebuggerManager.getDebuggerManager().removeDebuggerListener(debuggerStateListener);
  399. stopIfStartedByIde();
  400. // close the server io window
  401. if (getUrl() != null) {
  402. InputOutput io = UISupport.getServerIO(url);
  403. if (io != null && !io.isClosed()) {
  404. io.closeInputOutput();
  405. }
  406. ServerRegistry.getInstance().removeServerInstance(getUrl());
  407. } else {
  408. LOGGER.log(Level.WARNING, "Trying to remove {0}, but url is null", server != null ? server.getShortName() : null);
  409. }
  410. }
  411. /** Stop the server if it has been started from within the IDE, do nothing otherwise */
  412. public void stopIfStartedByIde() {
  413. if (managerStartedByIde) {
  414. if (canStopDontWait()) {
  415. stopDontWait();
  416. } else {
  417. String title = NbBundle.getMessage(ServerInstance.class, "LBL_ShutDownServer", getDisplayName());
  418. final ProgressUI progressUI = new ProgressUI(title, true, null);
  419. progressUI.start();
  420. RequestProcessor.getDefault().post(new Runnable() {
  421. public void run() {
  422. try {
  423. for (Iterator it = targetsStartedByIde.iterator(); it.hasNext();) {
  424. ServerTarget serverTarget = getServerTarget((String)it.next());
  425. if (serverTarget != null) {
  426. try {
  427. _stop(serverTarget.getTarget(), progressUI);
  428. } catch (ServerException ex) {
  429. Logger.getLogger("global").log(Level.INFO, null, ex);
  430. }
  431. }
  432. }
  433. if (isReallyRunning() || isSuspended()) {
  434. try {
  435. _stop(progressUI);
  436. } catch (ServerException ex) {
  437. Logger.getLogger("global").log(Level.INFO, null, ex);
  438. }
  439. }
  440. } finally {
  441. progressUI.finish();
  442. }
  443. }
  444. });
  445. progressUI.showProgressDialog();
  446. }
  447. }
  448. }
  449. /** Set the server state and notify all listeners */
  450. public void setServerState(int newState) {
  451. int oldState = serverState;
  452. serverState = newState;
  453. fireStateChanged(oldState, newState);
  454. }
  455. /** Return the current server state */
  456. public int getServerState() {
  457. return serverState;
  458. }
  459. /** Is it forbidden to remove this server instance from the server registry? */
  460. public boolean isRemoveForbidden() {
  461. String removeForbid = instanceProperties.getProperty(InstanceProperties.REMOVE_FORBIDDEN);
  462. return Boolean.valueOf(removeForbid).booleanValue();
  463. }
  464. /**
  465. * <i>This method can have ugly side effect of starting the server.</i>
  466. *
  467. * @return
  468. */
  469. public ServerTarget[] getTargets() {
  470. Map targets = getTargetMap();
  471. synchronized (this) {
  472. return (ServerTarget[]) targets.values().toArray(new ServerTarget[targets.size()]);
  473. }
  474. }
  475. public Collection getTargetList() {
  476. Map targets = getTargetMap();
  477. synchronized (this) {
  478. return targets.values();
  479. }
  480. }
  481. // PENDING use targets final variable?
  482. private Map getTargetMap() {
  483. Map tmpTargets = null;
  484. synchronized (this) {
  485. tmpTargets = targets;
  486. }
  487. if (tmpTargets == null || tmpTargets.size() < 1) {
  488. Target[] targs = null;
  489. StartServer startServer = getStartServer();
  490. // TODO revert the Glassfish /w profiler related workaround
  491. // once profiling uses the same startup sequence as debugging eg.
  492. try {
  493. if (! isRunning() && startServer != null && startServer.needsStartForTargetList()) {
  494. // GF workaround
  495. // the guard condition introduced
  496. // *** original line
  497. // start();
  498. // ***
  499. if (ProfilerSupport.getState() == ProfilerSupport.STATE_INACTIVE) {
  500. start();
  501. }
  502. // end of GF workaround
  503. }
  504. // GF workaround
  505. // a dealy loop introduced
  506. // *** original line
  507. // targs = getDeploymentManager().getTargets();
  508. // ***
  509. do {
  510. targs = getDeploymentManager().getTargets();
  511. if (targs == null && ProfilerSupport.getState() == ProfilerSupport.STATE_PROFILING) {
  512. try {
  513. Thread.sleep(500);
  514. } catch (InterruptedException ex) {
  515. Thread.currentThread().interrupt();
  516. }
  517. }
  518. } while (targs == null && ProfilerSupport.getState() == ProfilerSupport.STATE_PROFILING);
  519. // end of GF workaround
  520. } catch(IllegalStateException e) {
  521. LOGGER.log(Level.INFO, null, e);
  522. }
  523. if (targs == null) {
  524. targs = new Target[0];
  525. }
  526. tmpTargets = new HashMap();
  527. for (int i = 0; i < targs.length; i++) {
  528. tmpTargets.put(targs[i].getName(), new ServerTarget(this, targs[i]));
  529. }
  530. synchronized (this) {
  531. targets = tmpTargets;
  532. }
  533. }
  534. return tmpTargets;
  535. }
  536. public ServerTarget getServerTarget(String targetName) {
  537. return (ServerTarget) getTargetMap().get(targetName);
  538. }
  539. public Target getTarget(String targetName) {
  540. return getServerTarget(targetName).getTarget();
  541. }
  542. public StartServer getStartServer() {
  543. DeploymentManager dm = null;
  544. try {
  545. dm = getDisconnectedDeploymentManager();
  546. } catch (DeploymentManagerCreationException dmce) {
  547. Logger.getLogger(ServerInstance.class.getName()).log(Level.INFO, null, dmce);
  548. return null;
  549. }
  550. synchronized (this) {
  551. if (startServer == null) {
  552. startServer = server.getOptionalFactory().getStartServer(dm);
  553. }
  554. return startServer;
  555. }
  556. }
  557. public IncrementalDeployment getIncrementalDeployment() {
  558. DeploymentManager dm = getDeploymentManager();
  559. synchronized (this) {
  560. if (incrementalDeployment == null) {
  561. incrementalDeployment = server.getOptionalFactory().getIncrementalDeployment(dm);
  562. }
  563. return incrementalDeployment;
  564. }
  565. }
  566. public ServerInstanceDescriptor getServerInstanceDescriptor() {
  567. DeploymentManager dm = getDeploymentManager();
  568. synchronized (this) {
  569. if (instanceDescriptor == null) {
  570. instanceDescriptor = server.getOptionalFactory().getServerInstanceDescriptor(dm);
  571. }
  572. return instanceDescriptor;
  573. }
  574. }
  575. public AntDeploymentProvider getAntDeploymentProvider() {
  576. try {
  577. return server.getOptionalFactory().getAntDeploymentProvider(getDisconnectedDeploymentManager());
  578. } catch (DeploymentManagerCreationException ex) {
  579. Logger.getLogger("global").log(Level.INFO, null, ex);
  580. return null;
  581. }
  582. }
  583. public JDBCDriverDeployer getJDBCDriverDeployer() {
  584. try {
  585. return server.getOptionalFactory().getJDBCDriverDeployer(getDisconnectedDeploymentManager());
  586. } catch (DeploymentManagerCreationException ex) {
  587. Logger.getLogger("global").log(Level.INFO, null, ex);
  588. return null;
  589. }
  590. }
  591. public TargetModuleIDResolver getTargetModuleIDResolver() {
  592. DeploymentManager dm = getDeploymentManager();
  593. synchronized (this) {
  594. if (tmidResolver == null) {
  595. tmidResolver = server.getOptionalFactory().getTargetModuleIDResolver(dm);
  596. }
  597. return tmidResolver;
  598. }
  599. }
  600. public FindJSPServlet getFindJSPServlet() {
  601. DeploymentManager dm = null;
  602. try {
  603. dm = getDisconnectedDeploymentManager();
  604. } catch (DeploymentManagerCreationException dmce) {
  605. throw new RuntimeException(dmce);
  606. }
  607. synchronized (this) {
  608. if (findJSPServlet == null) {
  609. findJSPServlet = server.getOptionalFactory().getFindJSPServlet(dm);
  610. }
  611. return findJSPServlet;
  612. }
  613. }
  614. private DatasourceManager getDatasourceManager() {
  615. DeploymentManager dm = getDeploymentManager();
  616. synchronized (this) {
  617. if (dsMgr == null) {
  618. dsMgr = server.getOptionalFactory().getDatasourceManager(dm);
  619. }
  620. return dsMgr;
  621. }
  622. }
  623. private DatasourceManager getDisconnectedDatasourceManager() {
  624. DeploymentManager dm = null;
  625. try {
  626. dm = getDisconnectedDeploymentManager();
  627. } catch (DeploymentManagerCreationException dmce) {
  628. throw new RuntimeException(dmce);
  629. }
  630. synchronized (this) {
  631. if (ddsMgr == null) {
  632. ddsMgr = server.getOptionalFactory().getDatasourceManager(dm);
  633. }
  634. return ddsMgr;
  635. }
  636. }
  637. private ServerLibraryManager getServerLibraryManager() {
  638. DeploymentManager dm = getDeploymentManager();
  639. synchronized (this) {
  640. if (libraryManager == null) {
  641. libraryManager = server.getOptionalFactory().getServerLibraryManager(dm);
  642. }
  643. return libraryManager;
  644. }
  645. }
  646. private ServerLibraryManager getDisconnectedServerLibraryManager() {
  647. DeploymentManager dm = null;
  648. try {
  649. dm = getDisconnectedDeploymentManager();
  650. } catch (DeploymentManagerCreationException dmce) {
  651. throw new RuntimeException(dmce);
  652. }
  653. synchronized (this) {
  654. if (disconnectedLibraryManager == null) {
  655. disconnectedLibraryManager = server.getOptionalFactory().getServerLibraryManager(dm);
  656. }
  657. return disconnectedLibraryManager;
  658. }
  659. }
  660. /**
  661. * Gets the data sources deployed on the this server instance.
  662. *
  663. * @return set of data sources
  664. */
  665. public Set<Datasource> getDatasources() throws ConfigurationException {
  666. DatasourceManager ddsMgr = getDisconnectedDatasourceManager();
  667. Set deployedDS = Collections.<Datasource>emptySet();
  668. if (ddsMgr != null)
  669. deployedDS = ddsMgr.getDatasources();
  670. return deployedDS;
  671. }
  672. /**
  673. * Deploys data sources saved in the module.
  674. *
  675. * @exception ConfigurationException if there is some problem with data source configuration
  676. * @exception DatasourceAlreadyExistsException if module data source(s) are conflicting
  677. * with data source(s) already deployed on the server
  678. */
  679. public void deployDatasources(Set<Datasource> datasources) throws ConfigurationException, DatasourceAlreadyExistsException {
  680. DatasourceManager dsMgr = getDatasourceManager();
  681. if (dsMgr != null)
  682. dsMgr.deployDatasources(datasources);
  683. }
  684. public boolean isServerLibraryManagementSupported() {
  685. return getDisconnectedServerLibraryManager() != null;
  686. }
  687. public Set<ServerLibrary> getDeployableLibraries() {
  688. ServerLibraryManager libraryManager = getDisconnectedServerLibraryManager();
  689. Set<ServerLibrary> libraries = Collections.emptySet();
  690. if (libraryManager != null) {
  691. libraries = libraryManager.getDeployableLibraries();
  692. }
  693. return libraries;
  694. }
  695. public Set<ServerLibrary> getDeployedLibraries() {
  696. ServerLibraryManager libraryManager = getDisconnectedServerLibraryManager();
  697. Set<ServerLibrary> libraries = Collections.emptySet();
  698. if (libraryManager != null) {
  699. libraries = libraryManager.getDeployedLibraries();
  700. }
  701. return libraries;
  702. }
  703. public Set<ServerLibraryDependency> getDeployableDependencies(
  704. @NonNull Set<ServerLibraryDependency> dependencies) {
  705. ServerLibraryManager libraryManager = getDisconnectedServerLibraryManager();
  706. Set<ServerLibraryDependency> result = Collections.emptySet();
  707. if (libraryManager != null) {
  708. result = libraryManager.getDeployableDependencies(dependencies);
  709. }
  710. return result;
  711. }
  712. public Set<ServerLibraryDependency> getMissingDependencies(
  713. @NonNull Set<ServerLibraryDependency> dependencies) {
  714. ServerLibraryManager libraryManager = getDisconnectedServerLibraryManager();
  715. Set<ServerLibraryDependency> result = Collections.emptySet();
  716. if (libraryManager != null) {
  717. result = libraryManager.getMissingDependencies(dependencies);
  718. }
  719. return result;
  720. }
  721. public void deployLibraries(Set<ServerLibraryDependency> libraries) throws ConfigurationException {
  722. ServerLibraryManager libraryManager = getServerLibraryManager();
  723. if (libraryManager != null) {
  724. StartServer ss = getStartServer();
  725. if (ss != null && !ss.isRunning() && ss.needsStartForAdminConfig()) {
  726. start();
  727. }
  728. libraryManager.deployLibraries(libraries);
  729. }
  730. }
  731. private synchronized MessageDestinationDeployment getMessageDestinationDeploymentConnected() {
  732. if (msgDestDeploymentConnected == null) {
  733. msgDestDeploymentConnected = server.getOptionalFactory().
  734. getMessageDestinationDeployment(getDeploymentManager());
  735. }
  736. return msgDestDeploymentConnected;
  737. }
  738. private MessageDestinationDeployment getMessageDestinationDeploymentDisconnected() {
  739. DeploymentManager dm = null;
  740. try {
  741. dm = getDisconnectedDeploymentManager();
  742. } catch (DeploymentManagerCreationException dmce) {
  743. throw new RuntimeException(dmce);
  744. }
  745. synchronized (this) {
  746. if (msgDestDeploymentDisconnected == null) {
  747. msgDestDeploymentDisconnected = server.getOptionalFactory().getMessageDestinationDeployment(dm);
  748. }
  749. return msgDestDeploymentDisconnected;
  750. }
  751. }
  752. /**
  753. * Retrieves message destinations configured on the target server instance.
  754. *
  755. * @return set of message destinations
  756. *
  757. * @throws ConfigurationException if there is some problem with message destination configuration
  758. */
  759. public Set<MessageDestination> getMessageDestinations() throws ConfigurationException {
  760. MessageDestinationDeployment destDepl = getMessageDestinationDeploymentDisconnected();
  761. if (destDepl != null) {
  762. return destDepl.getMessageDestinations();
  763. }
  764. return Collections.<MessageDestination>emptySet();
  765. }
  766. /**
  767. * Deploys message destinations saved in the module.
  768. *
  769. * @param destinations set of message destinations
  770. *
  771. * @throws NullPointerException if destinations parameter is null
  772. * @throws ConfigurationException if there is some problem with message destination configuration
  773. */
  774. public void deployMessageDestinations(Set<MessageDestination> destinations) throws ConfigurationException {
  775. Parameters.notNull("destinations", destinations);
  776. MessageDestinationDeployment destDepl = getMessageDestinationDeploymentConnected();
  777. if (destDepl != null) {
  778. destDepl.deployMessageDestinations(destinations);
  779. }
  780. }
  781. //---------- State API's: running, debuggable, startedByIDE -----------
  782. public boolean isRunningLastCheck() {
  783. if (lastCheck > 0) {
  784. return isRunning;
  785. } else {
  786. return false;
  787. }
  788. }
  789. public boolean isReallyRunning() {
  790. return isRunningWithinMillis(0);
  791. }
  792. public boolean isRunning() {
  793. return isRunningWithinMillis(2000);
  794. }
  795. public boolean isRunningWithinMillis(long millisecs) {
  796. if (System.currentTimeMillis() - lastCheck < millisecs) {
  797. return isRunning;
  798. }
  799. final StartServer ss = getStartServer();
  800. if (ss != null) {
  801. isRunning = safeTrueTest(new SafeTrueTest() {
  802. public void run() {
  803. setResult(ss.isRunning());
  804. }
  805. },
  806. RUNNING_CHECK_TIMEOUT);
  807. } else {
  808. isRunning = false;
  809. }
  810. lastCheck = System.currentTimeMillis();
  811. return isRunning;
  812. }
  813. public boolean isDebuggable(final Target target) {
  814. final StartServer ss = getStartServer();
  815. if (ss != null) {
  816. return safeTrueTest(new SafeTrueTest() {
  817. public void run() {
  818. setResult(ss.isDebuggable(target));
  819. }
  820. },
  821. DEBUGGING_CHECK_TIMEOUT);
  822. } else {
  823. return false;
  824. }
  825. }
  826. /**
  827. * @return conflict data instance for server instance running in debug mode with the same socket number
  828. * or shared memory id. If no such server instance exists then null is returned.
  829. */
  830. public ConflictData anotherServerDebuggable(Target target) {
  831. ConflictData cd = null;
  832. //get debug info for this instance
  833. StartServer thisSS = getStartServer();
  834. if (thisSS == null) //this case should not occur =>
  835. return null; //attempt to start server (serverInstance remains null)
  836. ServerDebugInfo thisSDI = getServerDebugInfo(target);
  837. if (thisSDI == null) {
  838. Target t = _retrieveTarget(target);
  839. thisSDI = thisSS.getDebugInfo(t);
  840. if (thisSDI == null) {
  841. LOGGER.log(Level.FINE, "DebuggerInfo cannot be found for: " + this.toString());
  842. return null;
  843. }
  844. }
  845. //get all server instances
  846. ServerInstance[] serverInstances = ServerRegistry.getInstance().getServerInstances();
  847. //check existence of a server instance running in debug mode with the same parameters
  848. for (int i = 0; cd == null && i < serverInstances.length; i++) {
  849. ServerInstance si = serverInstances[i];
  850. if (url.equalsIgnoreCase(si.getUrl())) continue;
  851. if (si.isDebuggable(null)) { //running in debug mode
  852. Target t = si._retrieveTarget(null);
  853. ServerDebugInfo sdi = si.getServerDebugInfo(t);
  854. if (sdi == null) continue; //should not occur -> workaround for issue #56714
  855. if (thisSDI.getTransport().equals(sdi.getTransport())) { //transport matches
  856. if (thisSDI.getTransport() == ServerDebugInfo.TRANSPORT_SOCKET) {
  857. if (thisSDI.getHost().equalsIgnoreCase(sdi.getHost())) //host matches
  858. if (thisSDI.getPort() == sdi.getPort()) //port matches
  859. cd = new ConflictData(si, thisSDI);
  860. } else if (thisSDI.getShmemName().equalsIgnoreCase(sdi.getShmemName()))
  861. cd = new ConflictData(si, thisSDI);
  862. }
  863. }
  864. }
  865. return cd;
  866. }
  867. private JPDADebugger getDebugger() {
  868. Session[] sessions = DebuggerManager.getDebuggerManager().getSessions();
  869. Target target = _retrieveTarget(null);
  870. ServerDebugInfo sdi = getServerDebugInfo(target);
  871. if (sdi == null) {
  872. LOGGER.log(Level.FINE, "DebuggerInfo cannot be found for: " + this.toString());
  873. return null; // give user a chance to start server even if we don't know whether she will success
  874. }
  875. for (int i = 0; i < sessions.length; i++) {
  876. Session s = sessions[i];
  877. if (s == null) {
  878. continue;
  879. }
  880. Object o = s.lookupFirst(null, AttachingDICookie.class);
  881. if (o == null) {
  882. continue;
  883. }
  884. AttachingDICookie attCookie = (AttachingDICookie) o;
  885. if (sdi.getTransport().equals(ServerDebugInfo.TRANSPORT_SHMEM)) {
  886. String shmem = attCookie.getSharedMemoryName();
  887. if (shmem == null) {
  888. continue;
  889. }
  890. if (shmem.equalsIgnoreCase(sdi.getShmemName())) {
  891. Object d = s.lookupFirst(null, JPDADebugger.class);
  892. if (d != null) {
  893. return (JPDADebugger) d;
  894. }
  895. }
  896. } else {
  897. String host = attCookie.getHostName();
  898. if (host != null && isSameHost(host, sdi.getHost())
  899. && attCookie.getPortNumber() == sdi.getPort()) {
  900. Object d = s.lookupFirst(null, JPDADebugger.class);
  901. if (d != null) {
  902. return (JPDADebugger) d;
  903. }
  904. }
  905. }
  906. }
  907. return null;
  908. }
  909. /**
  910. * Returns true if this server is started in debug mode AND debugger is attached to it
  911. * AND threads are suspended (e.g. debugger stopped on breakpoint)
  912. */
  913. public boolean isSuspended() {
  914. JPDADebugger jpda = getDebugger();
  915. if (jpda == null) {
  916. return false;
  917. }
  918. return jpda.getState() == JPDADebugger.STATE_STOPPED;
  919. }
  920. /**
  921. * Can be this server started in the debug mode? Currently the only case when
  922. * the server cannot be started in the debugged is when the admin server is
  923. * not also the target server.
  924. *
  925. * @return <code>true</code> if the server can be started in the debug mode,
  926. * <code>false/code> otherwise.
  927. */
  928. public boolean isDebugSupported() {
  929. StartServer ss = getStartServer();
  930. if (ss == null) {
  931. return false;
  932. }
  933. return ss.supportsStartDebugging(null);
  934. }
  935. /**
  936. * Can be this server started in profile mode? Currently the only case when
  937. * the server cannot be started in the debugged is when the admin server is
  938. * not also the target server.
  939. */
  940. public boolean isProfileSupported() {
  941. Profiler profiler = ServerRegistry.getProfiler();
  942. if (profiler == null) {
  943. return false;
  944. }
  945. StartServer ss = getStartServer();
  946. if (ss == null) {
  947. return false;
  948. }
  949. return ss.supportsStartProfiling(null);
  950. }
  951. /**
  952. * Return set of ServerTarget's that have been started from inside IDE.
  953. * @return set of ServerTarget objects.
  954. */
  955. public Set getTargetsStartedByIde() {
  956. Set ret = new HashSet();
  957. for (Iterator i=targetsStartedByIde.iterator(); i.hasNext(); ) {
  958. String targetName = (String) i.next();
  959. ret.add(getServerTarget(targetName));
  960. }
  961. return ret;
  962. }
  963. //----------- State Transistion API's: ----------------------
  964. /**
  965. * Start the admin server. Show UI feedback.
  966. * Note: for debug mode, always use startDebugTarget() calls because
  967. * it is sure then the target need to be started.
  968. *
  969. * @throws ServerException if the server cannot be started.
  970. */
  971. public void start(ProgressUI ui) throws ServerException {
  972. try {
  973. setServerState(STATE_WAITING);
  974. startTarget(null, ui);
  975. } finally {
  976. refresh();
  977. }
  978. }
  979. /** Start the admin server in the debug mode. Show UI feedback.
  980. *
  981. * @throws ServerException if the server cannot be started.
  982. */
  983. public void startDebug(ProgressUI ui) throws ServerException {
  984. try {
  985. setServerState(STATE_WAITING);
  986. startTarget(null, ui, Deployment.Mode.DEBUG);
  987. _retrieveDebugInfo(null);
  988. } finally {
  989. refresh();
  990. }
  991. }
  992. /** Start the admin server in the profile mode. Show UI feedback.
  993. *
  994. * @throws ServerException if the server cannot be started.
  995. */
  996. public void startProfile(boolean forceRestart, ProgressUI ui)
  997. throws ServerException {
  998. // check whether another server not already running in profile mode
  999. // and ask whether it is ok to stop it
  1000. ServerInstance tmpProfiledServerInstance = profiledServerInstance.get();
  1001. if (tmpProfiledServerInstance != null && tmpProfiledServerInstance != this) {
  1002. String msg = NbBundle.getMessage(
  1003. ServerInstance.class,
  1004. "MSG_AnotherServerProfiling",
  1005. tmpProfiledServerInstance.getDisplayName());
  1006. NotifyDescriptor nd = new NotifyDescriptor.Confirmation(msg, NotifyDescriptor.OK_CANCEL_OPTION);
  1007. if (DialogDisplayer.getDefault().notify(nd) == NotifyDescriptor.CANCEL_OPTION) {
  1008. // start in profile mode has been cancelled
  1009. String err = NbBundle.getMessage(ServerInstance.class, "MSG_ProfilingCancelled", getDisplayName());
  1010. throw new ServerException(err);
  1011. }
  1012. }
  1013. try {
  1014. setServerState(STATE_WAITING);
  1015. // target == null - admin server
  1016. _startProfile(null, forceRestart, ui);
  1017. } finally {
  1018. refresh();
  1019. }
  1020. }
  1021. /** Restart the admin server in the mode the server was running in before.
  1022. * Show UI feedback.
  1023. *
  1024. * @throws ServerException if the server cannot be restarted.
  1025. */
  1026. public void restart(ProgressUI ui) throws ServerException {
  1027. try {
  1028. setServerState(STATE_WAITING);
  1029. boolean inDebug = isDebuggable(null);
  1030. boolean inProfile = profiledServerInstance.get() == this;
  1031. boolean stopped = true;
  1032. if (inProfile || isReallyRunning() || isSuspended()) {
  1033. _stop(ui);
  1034. }
  1035. if (stopped) {
  1036. // restart in the mode the server was running in before
  1037. if (inProfile) {
  1038. _startProfile(null, true, ui);
  1039. } else if (inDebug) {
  1040. startDebugTarget(null, ui);
  1041. } else {
  1042. startTarget(null, ui);
  1043. }
  1044. }
  1045. } finally {
  1046. refresh();
  1047. }
  1048. }
  1049. /** Stop admin server. Show UI feedback.
  1050. *
  1051. * @throws ServerException if the server cannot be stopped.
  1052. */
  1053. public void stop(ProgressUI ui) throws ServerException {
  1054. try {
  1055. setServerState(STATE_WAITING);
  1056. if (profiledServerInstance.get() == this || isReallyRunning() || isSuspended()) {
  1057. _stop(ui);
  1058. }
  1059. debugInfo.clear();
  1060. } finally {
  1061. refresh();
  1062. }
  1063. }
  1064. // Note: configuration needs
  1065. /**
  1066. * Return a connected DeploymentManager if needed by server platform for configuration
  1067. * @return DeploymentManager object for configuration.
  1068. */
  1069. public DeploymentManager getDeploymentManagerForConfiguration() throws DeploymentManagerCreationException {
  1070. StartServer ss = getStartServer();
  1071. if (ss != null && ss.needsStartForConfigure()) {
  1072. start();
  1073. return getDeploymentManager();
  1074. } else {
  1075. return getDisconnectedDeploymentManager();
  1076. }
  1077. }
  1078. // Note: execution only need these 3 state transition APIs
  1079. /**
  1080. * Start specified target server. If it is also admin server only make sure
  1081. * admin server is running.
  1082. * @param target target server to be started
  1083. * @param ui DeployProgressUI to display start progress
  1084. *
  1085. * @throws ServerException if the target cannot be started.
  1086. */
  1087. public void startTarget(Target target, ProgressUI ui) throws ServerException {
  1088. startTarget(target, ui, Deployment.Mode.RUN);
  1089. }
  1090. /**
  1091. * Start specified target server in debug mode. If target is also admin
  1092. * server only make sure admin server is running.
  1093. * @param target target server to be started
  1094. * @param ui DeployProgressUI to display start progress
  1095. *
  1096. * @throws ServerException if the server cannot be started.
  1097. */
  1098. public void startDebugTarget(Target target, ProgressUI ui) throws ServerException {
  1099. startTarget(target, ui, Deployment.Mode.DEBUG);
  1100. _retrieveDebugInfo(target);
  1101. }
  1102. /**
  1103. * Start admin server, mainly for registry actions with no existing progress UI
  1104. *
  1105. * @throws ServerException if the server cannot be started.
  1106. */
  1107. private void start() {
  1108. if (SwingUtilities.isEventDispatchThread()) {
  1109. //PENDING maybe a modal dialog instead of async is needed here
  1110. RequestProcessor.getDefault().post(new Runnable() {
  1111. public void run() {
  1112. start();
  1113. }
  1114. });
  1115. return;
  1116. }
  1117. if (isRunning()) {
  1118. return;
  1119. }
  1120. String title = NbBundle.getMessage(ServerInstance.class, "LBL_StartServerProgressMonitor", getDisplayName());
  1121. ProgressUI ui = new ProgressUI(title, false);
  1122. try {
  1123. ui.start();
  1124. start(ui);
  1125. } catch (ServerException ex) {
  1126. Logger.getLogger("global").log(Level.INFO, null, ex);
  1127. } finally {
  1128. ui.finish();
  1129. }
  1130. }
  1131. /**
  1132. * Start admin server for profiling, mainly for registry actions with no existing progress UI
  1133. * @param settings settings that will be used to start the server
  1134. *
  1135. * @throws ServerException if the server cannot be started.
  1136. */
  1137. public boolean startProfile(boolean forceRestart, Deployment.Logger logger) {
  1138. Str