Author: echatellier Date: 2009-12-17 16:34:04 +0100 (Thu, 17 Dec 2009) New Revision: 1716 Added: trunk/src/main/java/org/nuiton/util/war/JettyLauncher.java Modified: trunk/pom.xml trunk/src/main/java/org/nuiton/util/war/WinstoneLauncher.java trunk/src/site/apt/Warlauncher.apt Log: Add jetty implementation. Modified: trunk/pom.xml =================================================================== --- trunk/pom.xml 2009-12-17 14:10:00 UTC (rev 1715) +++ trunk/pom.xml 2009-12-17 15:34:04 UTC (rev 1716) @@ -64,6 +64,13 @@ </dependency> <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.7</version> + <scope>test</scope> + </dependency> + + <dependency> <groupId>org.jvnet.hudson.winstone</groupId> <artifactId>winstone</artifactId> <version>0.9.10-hudson-16</version> @@ -71,11 +78,12 @@ </dependency> <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <version>4.7</version> - <scope>test</scope> + <groupId>org.eclipse.jetty.aggregate</groupId> + <artifactId>jetty-webapp</artifactId> + <version>7.0.1.v20091125</version> + <scope>provided</scope> </dependency> + </dependencies> Added: trunk/src/main/java/org/nuiton/util/war/JettyLauncher.java =================================================================== --- trunk/src/main/java/org/nuiton/util/war/JettyLauncher.java (rev 0) +++ trunk/src/main/java/org/nuiton/util/war/JettyLauncher.java 2009-12-17 15:34:04 UTC (rev 1716) @@ -0,0 +1,256 @@ +/* *##% + * Copyright (C) 2009 Code Lutin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *##%*/ + +package org.nuiton.util.war; + +import java.awt.AWTException; +import java.awt.Desktop; +import java.awt.Image; +import java.awt.MenuItem; +import java.awt.PopupMenu; +import java.awt.SystemTray; +import java.awt.TrayIcon; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.io.File; +import java.io.IOException; +import java.net.JarURLConnection; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; + +import javax.swing.ImageIcon; + +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.DefaultHandler; +import org.eclipse.jetty.server.handler.HandlerCollection; +import org.eclipse.jetty.server.nio.SelectChannelConnector; +import org.eclipse.jetty.webapp.WebAppContext; + +/** + * War main class launcher (jetty based). + * + * To use it : + * java -jar app-xxx.war + * + * @author chatellier + * @version $Revision$ + * @since 1.1.2 + * + * Last update : $Date$ + * By : $Author$ + */ +public class JettyLauncher implements ActionListener, MouseListener { + + /** Jetty server instance. */ + protected Server jettyServer; + + /** Server URI. */ + protected URI serverUri; + + /** Default port. */ + protected int port = 8888; + + /** + * Main method (used by war in manifest). + * + * @param args args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + JettyLauncher launcher = new JettyLauncher(); + launcher.startServer(args); + launcher.installSystemTray(); + launcher.openBrowser(); + } + + /** + * Launch servlet container. + * + * @param args args + * @throws Exception + */ + protected void startServer(String[] args) throws Exception { + System.out.println("Starting server embedded mode..."); + + String fqnLauncherFile = JettyLauncher.class.getName().replaceAll("\\.", "/") + ".class"; + System.out.println("Search for launcher class : " + fqnLauncherFile); + + URL classFile = JettyLauncher.class.getClassLoader().getResource(fqnLauncherFile); + System.out.println(" - using classFile : " + classFile); + + // strange following line seams also work for jpnl launch + File me = new File(((JarURLConnection) classFile.openConnection()).getJarFile().getName()); + System.out.println(" - using warfile file : " + me); + + jettyServer = new Server(); + + Connector connector = new SelectChannelConnector(); + connector.setPort(port); + jettyServer.setConnectors(new Connector[]{connector}); + + WebAppContext webappcontext = new WebAppContext(); + webappcontext.setContextPath("/"); + webappcontext.setWar(me.getAbsolutePath()); + + HandlerCollection handlers= new HandlerCollection(); + handlers.setHandlers(new Handler[]{webappcontext, new DefaultHandler()}); + jettyServer.setHandler(handlers); + + jettyServer.start(); + + // build server uri + try { + serverUri = new URI("http://localhost:" + port); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + } + + /** + * Shutdown server. + */ + protected void stopServer() { + if (jettyServer != null) { + try { + jettyServer.stop(); + } catch (Exception e) { + e.printStackTrace(); + } + System.exit(0); + } + } + + /** + * Install system tray to stop server. + */ + protected void installSystemTray() { + if (SystemTray.isSupported()) { + // build menu + PopupMenu menu = new PopupMenu(); + MenuItem browserItem = new MenuItem("Start browser"); + browserItem.addActionListener(this); + browserItem.setActionCommand("browser"); + menu.add(browserItem); + + MenuItem stopItem = new MenuItem("Stop server"); + stopItem.addActionListener(this); + stopItem.setActionCommand("stop"); + menu.add(stopItem); + + // build tray icon + URL imageURL = JettyLauncher.class.getResource("/favicon.png"); + if (imageURL == null) { + imageURL = JettyLauncher.class.getResource("/favicon.jpg"); + } + if (imageURL == null) { + System.out.println("No favicon.{png|jpg} found, skip systray installation"); + } else { + Image image = new ImageIcon(imageURL).getImage(); + TrayIcon icon = new TrayIcon(image, "Server", menu); + icon.setImageAutoSize(true); + icon.addMouseListener(this); + + // System tray + SystemTray systemTray = SystemTray.getSystemTray(); + try { + systemTray.add(icon); + } catch (AWTException ex) { + throw new RuntimeException("Can't install tray icon", ex); + } + } + } + } + + /* + * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) + */ + @Override + public void actionPerformed(ActionEvent e) { + if ("browser".equalsIgnoreCase(e.getActionCommand())) { + openBrowser(); + } else if ("stop".equalsIgnoreCase(e.getActionCommand())) { + stopServer(); + } + } + + /** + * Open browser. + * + * @throws IOException + */ + protected void openBrowser() { + if (Desktop.isDesktopSupported() && serverUri != null) { + Desktop desktop = Desktop.getDesktop(); + if (desktop.isSupported(Desktop.Action.BROWSE)) { + System.out.println("Opening browser at " + serverUri); + try { + desktop.browse(serverUri); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + /* + * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent) + */ + @Override + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + openBrowser(); + } + } + + /* + * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent) + */ + @Override + public void mousePressed(MouseEvent e) { + + } + + /* + * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent) + */ + @Override + public void mouseReleased(MouseEvent e) { + + } + + /* + * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent) + */ + @Override + public void mouseEntered(MouseEvent e) { + + } + + /* + * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent) + */ + @Override + public void mouseExited(MouseEvent e) { + + } +} Property changes on: trunk/src/main/java/org/nuiton/util/war/JettyLauncher.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL" Modified: trunk/src/main/java/org/nuiton/util/war/WinstoneLauncher.java =================================================================== --- trunk/src/main/java/org/nuiton/util/war/WinstoneLauncher.java 2009-12-17 14:10:00 UTC (rev 1715) +++ trunk/src/main/java/org/nuiton/util/war/WinstoneLauncher.java 2009-12-17 15:34:04 UTC (rev 1716) @@ -42,7 +42,7 @@ import winstone.Launcher; /** - * War main class launcher. + * War main class launcher (winstone based). * * Based on winstone micro container. * Modified: trunk/src/site/apt/Warlauncher.apt =================================================================== --- trunk/src/site/apt/Warlauncher.apt 2009-12-17 14:10:00 UTC (rev 1715) +++ trunk/src/site/apt/Warlauncher.apt 2009-12-17 15:34:04 UTC (rev 1716) @@ -4,25 +4,23 @@ War launcher -* Winstone based +* Features -** Features - * Start embedded servlet container with current webapp * Favicon support * Systray with popup menu -** Use Winstone war launcher +* Prerequisites -*** Prerequisites - By default, winstone look for an icon named <<favicon.png>> or <<favicon.jpg>>. Il none of this icon is found, system tray won't work. -*** Maven configuration +* Use Winstone war launcher +** Maven configuration + Add following dependencies to your project. ------------------------------------------------ @@ -81,4 +79,65 @@ * Jetty based - <Comming soon...> +** Maven configuration + + Add following dependencies to your project. + +------------------------------------------------ +<dependency> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-utils</artifactId> + <version>1.1.2</version> + <scope>provided</scope> +</dependency> +<dependency> + <groupId>org.eclipse.jetty.aggregate</groupId> + <artifactId>jetty-webapp</artifactId> + <version>7.0.1.v20091125</version> + <scope>provided</scope> +</dependency> +<dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <version>2.5</version> + <scope>provided</scope> +</dependency> +------------------------------------------------ + + They have to be both at least in <<<provided>>> scope. + + Then, you need to add following configuration into maven-war-plugin : + +-------------------------------------------------------------------- +<plugin> + <artifactId>maven-war-plugin</artifactId> + <version>2.1-beta-1</version> + <configuration> + <archive> + <manifest> + <mainClass>org.nuiton.util.war.JettyLauncher</mainClass> + </manifest> + </archive> + <overlays> + <overlay> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-utils</artifactId> + <type>jar</type> + <includes> + <include>**/war/Jetty*</include> + </includes> + </overlay> + <overlay> + <groupId>org.eclipse.jetty.aggregate</groupId> + <artifactId>jetty-webapp</artifactId> + <type>jar</type> + </overlay> + <overlay> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <type>jar</type> + </overlay> + </overlays> + </configuration> +</plugin> +--------------------------------------------------------------------