GWT

org.mortbay.thread.Timeout. exception bei neuer GWT webapplication mit instantiations gwt designer oder windowbuilder pro

Wenn man eine neue WebApplication mit der GWT SDK 2.0.3 und der App Engine SDK 1.3.3 in eclipse erstellt und dabei den Instantiations WindowBuilder Pro oder den GWT Designer verwendet, dann taucht der folgende Fehler auf, wenn man versucht die “GWT application” (google nennt dies “Development Mode”) zu starten.

Exception in thread “main” java.lang.NoSuchMethodError: org.mortbay.thread.Timeout.<init>(Ljava/lang/Object;)V
at org.mortbay.io.nio.SelectorManager$SelectSet.<init>(SelectorManager.java:306)
at org.mortbay.io.nio.SelectorManager.doStart(SelectorManager.java:223)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:39)
at org.mortbay.jetty.nio.SelectChannelConnector.doStart(SelectChannelConnector.java:303)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:39)
at org.mortbay.jetty.Server.doStart(Server.java:233)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:39)
at com.google.gwt.dev.shell.jetty.JettyLauncher.start(JettyLauncher.java:543)
at com.google.gwt.dev.DevMode.doStartUpServer(DevMode.java:421)
at com.google.gwt.dev.DevModeBase.startUp(DevModeBase.java:1035)
at com.google.gwt.dev.DevModeBase.run(DevModeBase.java:783)
at com.google.gwt.dev.DevMode.main(DevMode.java:275)

Leider konnte ich bisher nicht herausfinden warum dies passiert, aber ich habe einen Workaround gefunden, mit dem man das Problem verhindern und umgehen kann:

Statt die App Engine SDK 1.3.3 beim Anlegen des neuen Web Application Projektes zu verwenden, erstellt man das Projekt zunächst unter Verwendung der App Engine SDK 1.3.1. Nachdem das Projekt erstellt ist, kann man mit einem Rechts-Klick auf das Projektverzeichnis (in eclipse) die Properties des Projektes ändern: Unter Google>App Engine kann man nun von der App Engine 1.3.1 die Einstellung auf die App Engine 1.3.3 ändern; das Projekt läuft dann ohne Probleme unter der neuen Engine.

select new appengine in the properties

select new appengine in the properties



Missing required argument ‘module[s]‘ Google Web Toolkit – jetty startet nicht in eclipse – project is not GWT project

Missing required argument ‘module[s]‘
Google Web Toolkit 2.0.3
DevMode [-noserver] [-port port-number | "auto"] [-whitelist whitelist-string] [-blacklist blacklist-string] [-logdir directory] [-logLevel level] [-gen dir] [-bindAddress host-name-or-address] [-codeServerPort port-number | "auto"] [-server servletContainerLauncher[:args]] [-startupUrl url] [-war dir] [-extra dir] [-workDir dir] module[s]

where
-noserver Prevents the embedded web server from running
-port Specifies the TCP port for the embedded web server (defaults to 8888)
-whitelist Allows the user to browse URLs that match the specified regexes (comma or space separated)
-blacklist Prevents the user browsing URLs that match the specified regexes (comma or space separated)
-logdir Logs to a file in the given directory, as well as graphically
-logLevel The level of logging detail: ERROR, WARN, INFO, TRACE, DEBUG, SPAM, or ALL
-gen Debugging: causes normally-transient generated types to be saved in the specified directory
-bindAddress Specifies the bind address for the code server and web server (defaults to 127.0.0.1)
-codeServerPort Specifies the TCP port for the code server (defaults to 9997)
-server Specify a different embedded web server to run (must implement ServletContainerLauncher)
-startupUrl Automatically launches the specified URL
-war The directory into which deployable output files will be written (defaults to ‘war’)
-extra The directory into which extra files, not intended for deployment, will be written
-workDir The compiler’s working directory for internal use (must be writeable; defaults to a system temp dir)
and
module[s] Specifies the name(s) of the module(s) to host

Nachdem man einige Zeit mit einem GWT-Projekt in eclipse gearbeitet hat, kann es passieren, daß das Projekt sich nicht mehr als “GWT application” unter Jetty startetn lassen will. Ich versuche derzeit noch herauszufinden was da genau passiert. In der wischenzeit möchte ich kurz erläutern, wie man das Problem umgehen kann:

1) In eclipse vom “Run”-Menü den Menüpunkt “Run Configurations …” auswählen

2) Dann unter “GWT Application” und “Web Application” die Konfigurationen des Projektes löschen

Das war alles. Danach kann man wieder normal aus dem Selektor das Projekt als “GWT Application” starten und es läuft wieder problemlos unter Jetty.

GWT Toolbar für RichTextArea (eine RichTextToolbar mit HTML-Editor)

Da es leider kein Standard-Widget für eine RichTextToolbar gibt, welche zudem die Möglichkeit hat zwischen HTML-Darstellung und WYSIWYG-Darstellung umzuschalten, habe ich eine einfache Implementierung einer Toolbar selbst geschrieben. Im folgenden sind Screenshots, sowie der komplette Quellcode der Toolbar zu finden. Die Toolbar ist kompatibel zu GWT 2.0, kann aber auch sehr einfach auf frühere Versionen downgegraded werden, wie zum Beispiel GWT 1.7.x. Wenn eine Version für GWT 1.7.x benötigt wird, so kann ich diese gerne zusenden. Bitte hierzu einfach eine Email an mich senden.

Für einen der besten Vorteile meiner Toolbar halte ich, daß sie sehr aufgeräumt ist. Ich hasse diese unlogisch aufgebauten und unstrukturierten Standard-Toolbars, wie sie derzeit überall üblich sind (wie z.B. auch die von Wordpress).Unstructured usual ToolBar

Dick, Kursiv, Durchgestrichen; aber Unterstrichen ist in der Zeile darunter zu finden. Dann kommen die Listen-Optionen; Einrückungen sind aber wiederum in der Zeile darunter. Oder die Ausrichtungen: Linksbündig, Zentriert und Rechtsbündig sind beisammen zu finden. Nur der Blocksatz ist wieder in einer Extra-Zeile:

Dahingehend nun meine Toolbar: Ich finde diese viel übersichtlicher und wesentlich benutzerfreundlicher:

RichText Toolbar with HTML and WYSIWYG-view for GWT RichTextArea

Und das ist der Quellcode der Toolbar. Um sie im eigenen Projekt zu nutzen, muß die Toolbar einfach instanziert werden mit einer Referenz zu der RichTextArea, auf die die Toolbar sich bezieht. Danach wird die Toolbar einfach wie ein normales Widget auf das Panel gelegt:

RichTextToolbar toolbar = new RichTextToolbar(yourRichTextArea);
stage.add(toolbar);
stage.add(yourRichTextArea);

Ok – und nun endlich der Quellcode, der auch bei code.google.com heruntergeladen werden kann:

-DEPRECATED VERSION-
See: https://code.google.com/p/richtexttoolbar/ for an actual copy
/**
/*
 * This software is published under the Apchae 2.0 licenses.
 * 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.
 * 
 * Author: Erik Scholtz 
 * Web: http://blog.elitecoderz.net
 */
 
package net.elitecoderz.blog;
 
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.RichTextArea;
import com.google.gwt.user.client.ui.ToggleButton;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.RichTextArea.Formatter;
 
public class RichTextToolbar extends Composite {
	private static final String HTTP_STATIC_ICONS_GIF = "http://blog.elitecoderz.net/wp-includes/js/tinymce/themes/advanced/img/icons.gif";
 
	/** Private Variables **/
	//The main (Vertical)-Panel and the two inner (Horizontal)-Panels
	private VerticalPanel outer;
	private HorizontalPanel topPanel;
	private HorizontalPanel bottomPanel;
 
	//The RichTextArea this Toolbar referes to and the Interfaces to access the RichTextArea
	private RichTextArea styleText;
	private Formatter styleTextFormatter;
 
	//We use an internal class of the ClickHandler and the KeyUpHandler to be private to others with these events
	private EventHandler evHandler;
 
	//The Buttons of the Menubar
	private ToggleButton bold;
	private ToggleButton italic;
	private ToggleButton underline;
	private ToggleButton stroke;
	private ToggleButton subscript;
	private ToggleButton superscript;
	private PushButton alignleft;
	private PushButton alignmiddle;
	private PushButton alignright;
	private PushButton orderlist;
	private PushButton unorderlist;
	private PushButton indentleft;
	private PushButton indentright;
	private PushButton generatelink;
	private PushButton breaklink;
	private PushButton insertline;
	private PushButton insertimage;
	private PushButton removeformatting;
	private ToggleButton texthtml;
 
	private ListBox fontlist;
	private ListBox colorlist;
 
	/** Constructor of the Toolbar **/
	public RichTextToolbar(RichTextArea richtext) {
		//Initialize the main-panel
		outer = new VerticalPanel();
 
		//Initialize the two inner panels
		topPanel = new HorizontalPanel();
		bottomPanel = new HorizontalPanel();
		topPanel.setStyleName("RichTextToolbar");
		bottomPanel.setStyleName("RichTextToolbar");
 
		//Save the reference to the RichText area we refer to and get the interfaces to the stylings
 
		styleText = richtext;
		styleTextFormatter = styleText.getFormatter();
 
		//Set some graphical options, so this toolbar looks how we like it.
		topPanel.setHorizontalAlignment(HorizontalPanel.ALIGN_LEFT);
		bottomPanel.setHorizontalAlignment(HorizontalPanel.ALIGN_LEFT);
 
		//Add the two inner panels to the main panel
		outer.add(topPanel);
		outer.add(bottomPanel);
 
		//Some graphical stuff to the main panel and the initialisation of the new widget
		outer.setWidth("100%");
		outer.setStyleName("RichTextToolbar");
		initWidget(outer);
 
		//
		evHandler = new EventHandler();
 
		//Add KeyUp and Click-Handler to the RichText, so that we can actualize the toolbar if neccessary
		styleText.addKeyUpHandler(evHandler);
		styleText.addClickHandler(evHandler);
 
		//Now lets fill the new toolbar with life
		buildTools();
	}
 
	/** Click Handler of the Toolbar **/
	private class EventHandler implements ClickHandler,KeyUpHandler, ChangeHandler {
		public void onClick(ClickEvent event) {
			if (event.getSource().equals(bold)) {
				if (isHTMLMode()) {
					changeHtmlStyle("<span style=\"font-weight: bold;\">","</span>");
				} else {
					styleTextFormatter.toggleBold();
				}
			} else if (event.getSource().equals(italic)) {
				if (isHTMLMode()) {
					changeHtmlStyle("<span style=\"font-style: italic;\">","</span>");
				} else {
					styleTextFormatter.toggleItalic();
				}
			} else if (event.getSource().equals(underline)) {
				if (isHTMLMode()) {
					changeHtmlStyle("<span style=\"text-decoration: underline;\">","</span>");
				} else {
					styleTextFormatter.toggleUnderline();
				}
			} else if (event.getSource().equals(stroke)) {
				if (isHTMLMode()) {
					changeHtmlStyle("<span style=\"text-decoration: line-through;\">","</span>");
				} else {
					styleTextFormatter.toggleStrikethrough();
				}
			} else if (event.getSource().equals(subscript)) {
				if (isHTMLMode()) {
					changeHtmlStyle("<sub>","</sub>");
				} else {
					styleTextFormatter.toggleSubscript();
				}
			} else if (event.getSource().equals(superscript)) {
				if (isHTMLMode()) {
					changeHtmlStyle("<sup>","</sup>");
				} else {
					styleTextFormatter.toggleSuperscript();
				}
			} else if (event.getSource().equals(alignleft)) {
				if (isHTMLMode()) {
					changeHtmlStyle("
<div style=\"text-align: left;\">","</div>
");
				} else {
					styleTextFormatter.setJustification(RichTextArea.Justification.LEFT);
				}
			} else if (event.getSource().equals(alignmiddle)) {
				if (isHTMLMode()) {
					changeHtmlStyle("
<div style=\"text-align: center;\">","</div>
");
				} else {
					styleTextFormatter.setJustification(RichTextArea.Justification.CENTER);
				}
			} else if (event.getSource().equals(alignright)) {
				if (isHTMLMode()) {
					changeHtmlStyle("
<div style=\"text-align: right;\">","</div>
");
				} else {
					styleTextFormatter.setJustification(RichTextArea.Justification.RIGHT);
				}
			} else if (event.getSource().equals(orderlist)) {
				if (isHTMLMode()) {
					changeHtmlStyle("
<ol>
	<li>","</li>
</ol>
");
				} else {
					styleTextFormatter.insertOrderedList();
				}
			} else if (event.getSource().equals(unorderlist)) {
				if (isHTMLMode()) {
					changeHtmlStyle("
<ul>
	<li>","</li>
</ul>
");
				} else {
					styleTextFormatter.insertUnorderedList();
				}
			} else if (event.getSource().equals(indentright)) {
				if (isHTMLMode()) {
					changeHtmlStyle("
<div style=\"margin-left: 40px;\">","</div>
");
				} else {
					styleTextFormatter.rightIndent();
				}
			} else if (event.getSource().equals(indentleft)) {
				if (isHTMLMode()) {
					//TODO nothing can be done here at the moment
				} else {
					styleTextFormatter.leftIndent();
				}
			} else if (event.getSource().equals(generatelink)) {
				String url = Window.prompt("Enter a link URL:", "http://");
				if (url != null) {
					if (isHTMLMode()) {
						changeHtmlStyle("<a href=\""+url+"\">","</a>");
					} else {
						styleTextFormatter.createLink(url);
					}
				}
			} else if (event.getSource().equals(breaklink)) {
				if (isHTMLMode()) {
					//TODO nothing can be done here at the moment
				} else {
					styleTextFormatter.removeLink();
				}
			} else if (event.getSource().equals(insertimage)) {
				String url = Window.prompt("Enter an image URL:", "http://");
				if (url != null) {
					if (isHTMLMode()) {
						changeHtmlStyle("<img src=\""+url+"\">","");
					} else {
						styleTextFormatter.insertImage(url);
					}
				}
			}  else if (event.getSource().equals(insertline)) {
				if (isHTMLMode()) {
					changeHtmlStyle("<hr style=\"width: 100%; height: 2px;\">","");
				} else {
					styleTextFormatter.insertHorizontalRule();
				}
			} else if (event.getSource().equals(removeformatting)) {
				if (isHTMLMode()) {
					//TODO nothing can be done here at the moment
				} else {
					styleTextFormatter.removeFormat();
				}
			} else if (event.getSource().equals(texthtml)) {
				if (texthtml.isDown()) {
					styleText.setText(styleText.getHTML());
				} else {
					styleText.setHTML(styleText.getText());
				}
			} else if (event.getSource().equals(styleText)) {
				//Change invoked by the richtextArea
			}
			updateStatus();
		}
 
		public void onKeyUp(KeyUpEvent event) {
			updateStatus();
		}
 
		public void onChange(ChangeEvent event) {
			System.out.println("fire");
			if (event.getSource().equals(fontlist)) {
				if (isHTMLMode()) {
					changeHtmlStyle("<span style=\"font-family: "+fontlist.getValue(fontlist.getSelectedIndex())+";\">","</span>");
				} else {
					styleTextFormatter.setFontName(fontlist.getValue(fontlist.getSelectedIndex()));
				}
			} else if (event.getSource().equals(colorlist)) {
				if (isHTMLMode()) {
					changeHtmlStyle("<span style=\"color: "+colorlist.getValue(colorlist.getSelectedIndex())+";\">","</span>");
				} else {
					styleTextFormatter.setForeColor(colorlist.getValue(colorlist.getSelectedIndex()));
				}
			}
		}
	}
 
	/** Native JavaScript that returns the selected text and position of the start **/
	public static native JsArrayString getSelection(Element elem) /*-{
		var txt = "";
		var pos = 0;
  		if (elem.contentWindow.getSelection) {
        	txt = elem.contentWindow.getSelection();
        	pos = elem.contentWindow.getSelection().getRangeAt(0).startOffset;
        } else if (elem.contentWindow.document.getSelection) {
        	txt = elem.contentWindow.document.getSelection();
        	pos = elem.contentWindow.document.getSelection().getRangeAt(0).startOffset;
  		} else if (elem.contentWindow.document.selection) {
        	txt = elem.contentWindow.document.selection.createRange().text;
        	pos = elem.contentWindow.document.selection.getRangeAt(0).startOffset;
        }
  		return [""+txt,""+pos];
	}-*/;
 
	/** Method called to toggle the style in HTML-Mode **/
	private void changeHtmlStyle(String startTag, String stopTag) {
		JsArrayString tx = getSelection(styleText.getElement());
		String txbuffer = styleText.getText();
		Integer startpos = Integer.parseInt(tx.get(1));
		String selectedText = tx.get(0);
		styleText.setText(txbuffer.substring(0, startpos)+startTag+selectedText+stopTag+txbuffer.substring(startpos+selectedText.length()));
	}
 
	/** Private method with a more understandable name to get if HTML mode is on or not **/
	private Boolean isHTMLMode() {
		return  texthtml.isDown();
	}
 
	/** Private method to set the toggle buttons and disable/enable buttons which do not work in html-mode **/
	private void updateStatus() {
		if (styleTextFormatter != null) {
			bold.setDown(styleTextFormatter.isBold());
			italic.setDown(styleTextFormatter.isItalic());
			underline.setDown(styleTextFormatter.isUnderlined());
			subscript.setDown(styleTextFormatter.isSubscript());
			superscript.setDown(styleTextFormatter.isSuperscript());
			stroke.setDown(styleTextFormatter.isStrikethrough());
		}
 
		if (isHTMLMode()) {
			removeformatting.setEnabled(false);
			indentleft.setEnabled(false);
			breaklink.setEnabled(false);
		} else {
			removeformatting.setEnabled(true);
			indentleft.setEnabled(true);
			breaklink.setEnabled(true);
		}
	}
 
	/** Initialize the options on the toolbar **/
	private void buildTools() {
		//Init the TOP Panel forst
		topPanel.add(bold = createToggleButton(HTTP_STATIC_ICONS_GIF,0,0,20,20,"Bold"));
		topPanel.add(italic = createToggleButton(HTTP_STATIC_ICONS_GIF,0,60,20,20,"Italic"));
		topPanel.add(underline = createToggleButton(HTTP_STATIC_ICONS_GIF,0,140,20,20,"Underline"));
		topPanel.add(stroke = createToggleButton(HTTP_STATIC_ICONS_GIF,0,120,20,20,"Stroke"));
		topPanel.add(new HTML("&nbsp;"));
		topPanel.add(subscript = createToggleButton(HTTP_STATIC_ICONS_GIF,0,600,20,20,"Subscript"));
		topPanel.add(superscript = createToggleButton(HTTP_STATIC_ICONS_GIF,0,620,20,20,"Superscript"));
		topPanel.add(new HTML("&nbsp;"));
		topPanel.add(alignleft = createPushButton(HTTP_STATIC_ICONS_GIF,0,460,20,20,"Align Left"));
		topPanel.add(alignmiddle = createPushButton(HTTP_STATIC_ICONS_GIF,0,420,20,20,"Align Center"));
		topPanel.add(alignright = createPushButton(HTTP_STATIC_ICONS_GIF,0,480,20,20,"Align Right"));
		topPanel.add(new HTML("&nbsp;"));
		topPanel.add(orderlist = createPushButton(HTTP_STATIC_ICONS_GIF,0,80,20,20,"Ordered List"));
		topPanel.add(unorderlist = createPushButton(HTTP_STATIC_ICONS_GIF,0,20,20,20,"Unordered List"));
		topPanel.add(indentright = createPushButton(HTTP_STATIC_ICONS_GIF,0,400,20,20,"Ident Right"));
		topPanel.add(indentleft = createPushButton(HTTP_STATIC_ICONS_GIF,0,540,20,20,"Ident Left"));
		topPanel.add(new HTML("&nbsp;"));
		topPanel.add(generatelink = createPushButton(HTTP_STATIC_ICONS_GIF,0,500,20,20,"Generate Link"));
		topPanel.add(breaklink = createPushButton(HTTP_STATIC_ICONS_GIF,0,640,20,20,"Break Link"));
		topPanel.add(new HTML("&nbsp;"));
		topPanel.add(insertline = createPushButton(HTTP_STATIC_ICONS_GIF,0,360,20,20,"Insert Horizontal Line"));
		topPanel.add(insertimage = createPushButton(HTTP_STATIC_ICONS_GIF,0,380,20,20,"Insert Image"));
		topPanel.add(new HTML("&nbsp;"));
		topPanel.add(removeformatting = createPushButton(HTTP_STATIC_ICONS_GIF,20,460,20,20,"Remove Formatting"));
		topPanel.add(new HTML("&nbsp;"));
		topPanel.add(texthtml = createToggleButton(HTTP_STATIC_ICONS_GIF,0,260,20,20,"Show as HTML"));
 
		//Init the BOTTOM Panel
		bottomPanel.add(fontlist = createFontList());
		bottomPanel.add(new HTML("&nbsp;"));
		bottomPanel.add(colorlist = createColorList());
	}
 
	/** Method to create a Toggle button for the toolbar **/
	private ToggleButton createToggleButton(String url, Integer top, Integer left, Integer width, Integer height, String tip) {
		Image extract = new Image(url, left, top, width, height);
		ToggleButton tb = new ToggleButton(extract);
		tb.setHeight(height+"px");
		tb.setWidth(width+"px");
		tb.addClickHandler(evHandler);
		if (tip != null) {
			tb.setTitle(tip);
		}
		return tb;
	}
 
	/** Method to create a Push button for the toolbar **/
	private PushButton createPushButton(String url, Integer top, Integer left, Integer width, Integer height, String tip) {
		Image extract = new Image(url, left, top, width, height);
		PushButton tb = new PushButton(extract);
		tb.setHeight(height+"px");
		tb.setWidth(width+"px");
		tb.addClickHandler(evHandler);
		if (tip != null) {
			tb.setTitle(tip);
		}
		return tb;
	}
 
	/** Method to create the fontlist for the toolbar **/
	private ListBox createFontList() {
	    ListBox mylistBox = new ListBox();
	    mylistBox.addChangeHandler(evHandler);
	    mylistBox.setVisibleItemCount(1);
 
	    mylistBox.addItem("Fonts", "");
	    mylistBox.addItem("Times New Roman", "Times New Roman");
	    mylistBox.addItem("Arial", "Arial");
	    mylistBox.addItem("Courier New", "Courier New");
	    mylistBox.addItem("Georgia", "Georgia");
	    mylistBox.addItem("Trebuchet", "Trebuchet");
	    mylistBox.addItem("Verdana", "Verdana");
	    return mylistBox;
	}
 
	/** Method to create the colorlist for the toolbar **/
	private ListBox createColorList() {
	    ListBox mylistBox = new ListBox();
	    mylistBox.addChangeHandler(evHandler);
	    mylistBox.setVisibleItemCount(1);
 
	    mylistBox.addItem("Colors");
	    mylistBox.addItem("white", "white");
	    mylistBox.addItem("black", "black");
	    mylistBox.addItem("red", "red");
	    mylistBox.addItem("green", "green");
	    mylistBox.addItem("yellow", "yellow");
	    mylistBox.addItem("blue", "blue");
	    return mylistBox;
	}
 
}
-DEPRECATED VERSION-
See: https://code.google.com/p/richtexttoolbar/ for an actual copy

Ich benutze folgende Icons in diesem Beispiel:
Hier ist der Link zu den Icons, welche ich selbst auch verwende

GWT und tomcat: .war erzeugen mit eclispe um .war auf tomcat zu deployen

Wie man mit eclipse kompfortabel ein .war aus einem GWT-Projekt erzeugt, um es auf einem tomcat-Server zu deployen.

Im Grunde genommen sind es nur zwei einfache Schritte, um aus dem GWT-Projekt ein .war zu erzeugen:

Kurzversion:

Als erstes wird ein .jar aus dem “src”-Verzeichnis des Projektes generiert, welches in das “lib”-Verzeichnis des “war”-Verzeichnisses des GWT-Projektes gelegt werden muß. Der zweite Schritt ist dann das eigentliche generieren der .war-Datei, welche dann auf den tomcat-server deployed werden kann. Um den zweiten Schritt etwas kompfortabler zu gestalten habe ich hierfür ein Ant-Script geschrieben, welches das eigentliche .war erzeugt.

Detailierte Version – Schritt 1:

right_click_src

1) Rechts-Klick auf das "src"-Verzeichnis (anklicken für größere Darstellung)

1) Rechts-Klick auf das src Verzeichnis innerhalb des Projektes.

popup_export

2) "Export" anklicken (anklicken für größere Darstellung)

2) Das nebenstehende PopUp erscheint.

Aus diesem Menü “Export …” wählen.

Select_export_format

3) Exportformat: "JAR File" (anklicken für größere Darstellung)

3) Nun “JAR file” als Export-Format wählen

select_export_source_and_target

3) Quelle und Ziel auswählen (anklicken für größere Darstellung)

4) Es darf nur das “src”-Verzeichnis des Projektes ausgewählt sein.

Als Ziel für den Export muß folgender Pfad angegeben werden: <Verzeichnis des Projektes>/war/WEB-INF/lib/<projectname>.jar – dann auf “Finish” klicken.

Nun ist das GWT-Projekt soweit vorbereitet, daß es in ein .war gepackt werden kann um auf einem tomcat-Server deployed zu werden.

Detailierte Version – Schritt 2:

1) Es wird ein neues ANT-Script innerhalb des Projektes erstellt (Rechts-Klick auf das Projektverzeichnis, dann “New” und vom Untermenü “File” auswählen. Die neue Datei sollte z.B. “warbuilder.xml” heissen).

2) Folgender Inhalt muß in diese Datei kopiert werden. Dabei <projectname> durch den Namen des Projektes ersetzen:

<project name="<projectname>" basedir="." default="default">
 
	<target name="default" depends="buildwar,deploy"></target>
 
	<target name="buildwar">
		<war basedir="war" destfile="
<projectname>.war" webxml="war/WEB-INF/web.xml">
			<exclude name="WEB-INF/**" />
			<webinf dir="war/WEB-INF/">
				<include name="**/*.jar" />
			</webinf>
		</war>
	</target>
 
	<target name="deploy">
		<copy file="
<projectname>.war" todir="." />
	</target>
 
</project>
run_ant_script

5) Run the warbuilder ANT-script (click for larger view)

3) Die ersten beiden Schritte müssen für jedes Projekt nur einmal ausgeführt werden. Danach kann der warbuilder.xml immer wieder benutzt werden. Um das .war nun zu erzeugen klickt man einfach mit der rechten Maustaste auf den warbuilder.xml und wählt vom PopUp-Menü den Punkt “Run as” und vom Submenü “Ant Build” aus.

Die .war-Datei wird dann durch das ANT-Script erzeugt. You will find the .war-file in your ProjectFolder.

GWT – java.lang.NoClassDefFoundError bei der Verwendung von .jars mit eclipse

10.12.2009 19:19:19 com.google.apphosting.utils.jetty.JettyLogger warn
WARNUNG: Nested in javax.servlet.ServletException: init:
java.lang.NoClassDefFoundError: org/jibble/pircbot/PircBot
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:675)

project_right_clickDiese Exception kann auftreten, wenn man versucht ein externes .jar mit GWT für die Serverseite zu verwenden. Die Fehlermeldung sagt aus, daß der eingebundene Pfad zu dem .jar (in diesem Fall org.jibble.pircbot.PircBot) nicht gefunden werden kann. Dies passiert normalerweise nur dann, wenn der Pfad zu dem .jar im JAVA Build Path nicht gesetzt wurde. Wenn man mit GWT arbeitet, ist das aber leider nicht alles was getan werden muß:

Der übliche Weg ein .jar einzubinden ist, die Einstellungen des Projektes zu bearbeiten, indem man mit der rechtenProject Properties Maustaste auf das Projekt klickt und aus dem PopUp-Menu “Eigenschaften” oder “Properties” wählt. In dem erscheinenden Fenster wählt man dann “Java Build Path” und ergänzt hier dann die externen .jars.

Wenn man das GWT-Plugin für eclipse verwendet, dann ist das nicht die einzige Stelle wo das .jar ergänzt werden muß. Zusätzlich muß hier das .jar noch in das WAR-Verzeichnis des Projektes kopiert werden. Um genau zu sein muß das .jar in folgendem Pfad abgelegt werden: YouProject/war/WEB-INF/lib/.

Nachdem man das .jar dort abgelegt hat, wird die lokale GWT-Runtime ohne weitere Fehlermeldung funktionieren. Der Hintergrund dazu ist folgender: Die GWT-Runtime des eclipse Plugins verwendet nicht die eclipse-Umgebung, sondern läuft ausschließlich aus dem “war”-Verzeichnis des Projektes, welches später auch auf den Application-Server deployed wird.

Get in contact:

Kategorien