Category Archives: Spring

Spring WS difficulties or lack of documentation

В этот раз история будет о неожидонных сложностях, возникшых с одним из замечательных модулей Spring, а именно Spring WS.

На проекте возникла необходимость написания WebService с нуля, было решено использовать Spring и стандартные технологии  в качестве связующей платформы в пользу проприетарных BEA, а теперь уже Oracle принадлежащих решениях. В частности для слоя работы с базой данных мы решили использовать JPA, а в качестве провайдера OpenJPA, до этоо в компании использовалось DSP, честно, первый раз услышал, разбираться не стали. Для WebService стека соответственно Spring WS, вместо чистого JAX WS со связкой через EJB, DAO и BO слои, вы можете сказать, что JAX WS это тоже стандарт, да не могу с вами не согласиться, но Spring WS находится на грани между стандартами и предоставляет гибкость при использовани разных технологий.

В общем после выбора технологий мы принялись за реализацию, и тут нас настигли небольшие трудности… Spring WS навязывает использование подхода – сначала XML потом Java код, это объясняется необхоимостью обеспечения портированности. Это достигается за счет того, что вы продумываете используемые типы данных в WebService и при генерации кода, можно получить не только для языка, с которым вы работаете, но и для любого другого, либо с вашим WebService сможет работать лубой другой клиент, написанный на любом языке.

Так же одной из еще возникших непонятностей, это возвращаемые и принимаемые на вход аргументы и их типы. Как оказалось после дебага в течении итеративных правок кода, сборки, деплоя на WebLogic, и запуском SOATest на запущенном в режиме отладки WebService, было выяснено, что WSDL, предложенный нам архитекторами не совместим с подходом Spring WS. В частности по привычке работы с JAX WS, методы WebService принимали несколько аргументов как примитивных, так и комплексных типов, что так же было присуще и возвращаемым типам данных. По-началу мысли были в стороне приведения типов аргументов и возвращаемых значений к примитивным, но этот фокус не удался. После дальнейшего “дебага” мы наконец-то поняли – Spring WS поддерживает в качестве аргумента только комплексный тип, описанный в XML, при чем аргумент должен быть один. Ну и возвращаемый тип значения тоже должен быть комплексным и описанным в XML. Таким образом если вы возвращаете значение примитивного типа, то вам нужно обвернуть его в комплексный тип и задекларировать в XML (WSDL или XSD).

После приведенных выше правок, наш WebService закрутился на ура, оставалось соглавсовать наши правки в WSDL с архитекторами.

На первый взгляд упомянутые выше ограничения не логичны, но если поразмыслить, то все становится на свои места. Делая обвертки для множества аргументов и примитивных типов возвращаемых значений в виде комплексного типа, мы увеличиваем уровень абстракции и инкапсуляции WebService.

На этом пожалуй мое повествование можно считать завершенным.

Всем удачи и ожидаемых ожиданий 😉

Google AppEngine first look

С недавних пор свое свободное время посвящаю реализации одной затеи в качестве платформы мы решили испоьзовать Google AppEngine для Java. И как оно обычно бывает с новыми и относительно неизвестными технологиями, с GAE это как оказалось – не исклбючение, появилось много проблем.

Проблемы в основном заключаются в сыроватости предоставляемых интерфейсов и органиченности их возможностей, думаю пока.

Начиналось все довольно спокойно – я установил SDK, поколдовал над рабочим окружением, что бы стало удобно работать и пустился в кодинг.

В моих планах было исследовать возможность работы Spring Framework 3.0.x, в частности меня интересует Spring MVC, а в качестве View – обычные старые добрые JSP. Со “спрингом” проблем особых не было, завелся, как говориться с пол пинка;).

Далее  – в качестве слоя для работы с базой взор был остановлен на JPA. Почему – потому что знакома и относительно привык работать с этой технологией. Но вот тут-то и начались “приколы”. Да на первый взгляд все заработало, но. Перечень “па” с бубном:

  • если вы используете Flex или GWT (как я) и хотите работать с объектами на стороне клиента, то одним из возможных подходов есть использование DTO объектов. В качестве конвертера объектов модели и объектов для клиентов я использую Dozer. И как оказалось в моем случае, из-за ограниченности в вариациях типов PrimaryKey, мне пришлось настраивать кастомные мапперы. В качестве PrimaryKey я использую предоставляемы Datastore тип Key, а клиент хранит его в виде строкового представления. До этого момента я получал сообщения об ошибках различного рода, связанные с ClassLoader-ом, с отсутствием поддержки типов ключей и т.д;
  • отсутствие поддержки связей. То есть если вам необходимо создать отношение One-To-Many, Many-To-Many или Many-To-One – у вас не будет возможности это сделать стандартным подходом. Это делается путем сохранения в ссылки на объект через его Key и последующей выборкой в случае необходимости. Не очень удобно, но работает. Надеюсь этого будет не всегда;
  • интересный нюанс с EntityManager.persist() или EntityManager.merge() – пока не вызовешь EntityManager.flush(), объект не будет сохранен. То есть если мне сразу же нужно вернуть сохраненный объект как результат выполнения метода, то я получу только то, что передал, хотя объект будет сохранен, но после.
  • еще вылезла проблема с использованием Spring Forms тегов. Немного погуглив, нашел решение проблемы – добавить в декларацию JSP аттрибут isELIgnored=”false” и переопределить PropertyEditors для каждого типа, используемого в бине, представляющем форму.

Так же еще одной из задач, которую нужно было решить – это подъем локального GAE сервера (в качестве сервлет контейнера используется Jetty) совместно с запуском GWT в дебаг-режиме. Тут конечно пришлось попотеть, т.к. стандартный подход Google к структуре проектов и отсутствие нативной поддержки с помощью Maven вынуждает к этому. Проблемы в основном были опять же с определением что откуда должно грузиться и совмещение это с тем, как мне нужно. После продолжительных не замысловатых действий вида “добавить ресурс, удалить ресурс” у меня все получилось. Теперь мой проект стартует из распакованного war-ника, поднимает Spring-контекст и подтягивает изменения в GWT на лету без перекомпиляции – то, что надо. Правда еще бы хотелось править JSP , без необходимости их последующего копирования в дерево проекта, но тогда придется жертвовать “чистотой” исходников проекта. Далее привожу свой конфиг для запуска GWT приложения в GAE контейнере.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
	<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
		<listEntry value="/webapp-ui" />
	</listAttribute>
	<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
		<listEntry value="4" />
	</listAttribute>
	<mapAttribute key="org.eclipse.debug.core.environmentVariables">
		<mapEntry key="JAVA_OPTS" value="-Xms128M -Xmx512M -XX:MaxPermSize=256M" />
		<mapEntry key="-Dappengine.sdk.root" value="D:\src\lib\gae-1.2.5" />
	</mapAttribute>
	<stringAttribute key="org.eclipse.debug.core.source_locator_id"
		value="org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector" />
	<stringAttribute key="org.eclipse.debug.core.source_locator_memento"
		value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;sourceLookupDirector&gt;&#13;&#10;&lt;sourceContainers duplicates=&quot;false&quot;&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;restio&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;lib-controller&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;lib-domain&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;lib-model&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;lib-service&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;lib-service-impl&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;mvp4g&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;webapp-ui&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;/sourceContainers&gt;&#13;&#10;&lt;/sourceLookupDirector&gt;&#13;&#10;" />
	<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
		<listEntry
			value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;com.google.appengine.eclipse.core.GAE_CONTAINER&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#13;&#10;" />
		<!-- GWT 2.x feature - ability to start HostedMode within browser -->
		<listEntry
			value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry externalArchive=&quot;D:/src/repository/com/google/gwt/gwt-dev-oophm/2.0.0/gwt-dev-oophm-2.0.0.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;" />
		<listEntry
			value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry externalArchive=&quot;D:/src/repository/commons-configuration/commons-configuration/1.6/commons-configuration-1.6.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;" />
		<listEntry
			value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;com.google.gwt.eclipse.core.GWT_CONTAINER&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#13;&#10;" />
		<listEntry
			value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry externalArchive=&quot;D:/src/repository/name/webdizz/rest/io/lib-service/0.0.1/lib-service-0.0.1.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;" />
		<listEntry
			value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry externalArchive=&quot;D:/src/repository/com/mvp4g/mvp4g/1.0-SNAPSHOT/mvp4g-1.0-SNAPSHOT.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;" />
		<listEntry
			value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/gwt-widget/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;" />
		<listEntry
			value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/lib-domain/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;" />
		<listEntry
			value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/lib-service/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;" />
		<listEntry
			value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/gwt-base/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;" />
		<listEntry
			value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/webapp-ui/src/main/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;" />
		<listEntry
			value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/webapp-ui/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;" />
		<listEntry
			value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/webapp-ui/src/main/webapp&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;" />
	</listAttribute>
	<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER"
		value="org.maven.ide.eclipse.launchconfig.classpathProvider" />
	<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH"
		value="false" />
	<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER"
		value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/1.6" />
	<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE"
		value="com.google.gwt.dev.HostedMode" />
	<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS"
		value="-startupUrl /view/&#13;&#10;-war D:\tmp\restio\webapp-ui\webapp-ui&#13;&#10;-server com.google.appengine.tools.development.gwt.AppEngineLauncher&#13;&#10;name.webdizz.rest.io.ui.Engine" />
	<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR"
		value="webapp-ui" />
	<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER"
		value="org.maven.ide.eclipse.launchconfig.sourcepathProvider" />
	<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS"
		value="-Xmx512M" />
	<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY"
		value="D:\tmp\restio\webapp-ui\webapp-ui" />
</launchConfiguration>

Хотел было прокомментировать код, но начав, понял – это не очень уместно т.к. названия он интуитивно понятен.
На это все, продолжим исследования…

GWT 1.7 on SpringSource dm Server 2.0.0.M3 UPD

В продолжении исследований GWT в совокупности с dmServer я наткнулся на одну загадочную поначалу проблему – сериализация.

Что это такое сериализация. Я не буду рассматривать и рассказывать, что собой представляет сериализация и для чего она нужна – это вы можете легко узнать, благо в сети найдутся хорошие публикации на эту тему, в данном же контексту меня интересует сериализация, которую использует GWT-RPC. GWT-RPC – это подход, который используется в GWT для осуществления I/O общения между клиентской  и серверной частами приложения. Этот подход позволяет оперировать с Java-объектами на стороне клиента, но есть определенное количество нюансов, о которых можно узнать по приведенной выше ссылке.

В моей ситуации произошла следующая ситуация. Мое приложение имеет слой для работы с базой данных с помошью JPA и в качестве JPA Provider я использую Hibernate. Так же у меня имеется DTOs, с которыми оперируют интерфейсы приложения, об Entity объектах знают только имплементации сервисных интерфейсов. Сервисы менеджется и публикуются в OSGi Service Registry Spring-ом. Клиентское приложение получает ссылку на сервис с помошью специального сервлета, который немного расширяет функционал RemoteServiceServlet и предоставляет возможность по названияю сервиса получать ссылку на него из Spring WebApplication Context.
Continue reading GWT 1.7 on SpringSource dm Server 2.0.0.M3 UPD

Отладка GWT приложений на внешнем контейнере

Background

В предыдущем посте было упомянуто о необходимости запускать GWT приложение в Hosted Mode, используя при этом dmServer, тут же я бы хотел поделиться шагами, через которые мне пришлось пройти, чтобы реализовать эту возможность.

Итак как это было…

Прочитав FAQ тут, как говорится с “пол пинка” не завелось к сожалению( Но на этом мое намерение отлаживать мое приложение в dmServer не испарилось. Что я сделал – изменил настройки ланчера для запуска приложения в Hosted Mode: изменил параметр для открытия URL -startupUrl и добавил парметр, говорящий ланчеру не запускать встроенный сервлет контейнер (для GWT 1.7 – Jetty). Содержимое конфигурационного файла приведено ниже.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
	<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
		<listEntry value="/stock-watcher" />
	</listAttribute>
	<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
		<listEntry value="4" />
	</listAttribute>
	<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables"
		value="true" />
	<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
		<listEntry
			value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER&quot; javaProject=&quot;stock-watcher&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;" />
		<listEntry
			value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/stock-watcher/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;" />
		<listEntry
			value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#13;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;stock-watcher&quot;/&gt;&#13;&#10;&lt;/runtimeClasspathEntry&gt;&#13;&#10;" />
	</listAttribute>
	<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER"
		value="org.maven.ide.eclipse.launchconfig.classpathProvider" />
	<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH"
		value="false" />
	<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE"
		value="com.google.gwt.dev.HostedMode" />
	<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS"
		value="-startupUrl http://localhost:8080/stock-watcher/StockWatcher.html&#13;&#10;name.webdizz.gwt.stock.watcher.StockWatcher&#13;&#10;-war src/main/webapp&#13;&#10;-noserver" />
	<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR"
		value="stock-watcher" />
	<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER"
		value="org.maven.ide.eclipse.launchconfig.sourcepathProvider" />
	<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS"
		value="-Xmx256M" />
</launchConfiguration>

На этом мои действия, исходя из смысла приведенной выше статьи, должны были увенчаться успехом, но это было не совсем так. Дальнейшие “танцы с бубном” показали, что так как я использую Maven для сборки проекта и, в частности, gwt-maven-plugin для компиляции GWT специфичных артифактов, проблема скрывалась за несогласованными действиями Google Eclipse plugin и Maven. Этот момент был устранен настройкой maven-war-plugin в файле pom.xml проекта stock-watcher. Я исключил копирование содержимого директории src/main/webapp/stockwatcher из src/main/webapp/ (директива warSourceExcludes).

46
47
48
49
50
51
52
<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-war-plugin</artifactId>
	<configuration>
		<warSourceExcludes>**/stockwatcher/**</warSourceExcludes>
	</configuration>
</plugin>

`После этого собранный проект с помошью команды

mvn clean install

Результат сборки копируем в pickup директорию dmServer-а и запускаем ланчер в Eclipse. Ставим breakpoint и наслаждаемся…;) правда перед тем как окунуться в дебаг не знаю почему, но необходимо Hosted Browser рефрешить 5 раз и на 6-ой мы попадаем на точку останова)).

Debugging GWT application
Debugging GWT application

GWT 1.7 on SpringSource dm Server 2.0.0.M3 Part2

Previous background:

В этом посте я продолжу повествование о попытке запуска GWT приложения в виде OSGi бандла в dmServer-е. В предыдущем посте мы немного изменили структуру проекта, поправили сборку проекта с помошью Ant и запустили приложение в dmServer-е как обычный war-ник.

What next:

В данном посте мы попытаемся создать OSGi бандл из нашего war-ника и задеплоить его в dmServer, а также перевести сборку проекта с помошью Ant на Maven, что в будущем будет более эффективно и гибко. Let’s go)

Continue reading GWT 1.7 on SpringSource dm Server 2.0.0.M3 Part2

GWT 1.7 on SpringSource dm Server 2.0.0.M3

Вводная часть

Хочу описать шаги, проделываемые мной, для того, что бы заставить работать GWT в SpringSource dm Server версии 2.0.0.M3 (далее dmServer). Мои попытки базируются на серии статей отсюда http://blog.springsource.com/2008/11/07/deploying-gwt-applications-in-springsource-dm-server-part-1/. Также хотелось бы интегрировать Maven в сборку проекта.

Мы будем использовать:

  • dmServer 2.0.0.M3;
  • SpringFrameWork 3.0.0.M3;
  • GWT 1.7

Итак начнем…

Step 1: создаем новый GWT проект

Добавляем в PATH путь к распакованному дистрибутиву с GWT

set PATH=%PATH%;D:\projects\gwt\gwt-dist

и выполняем комманду для создания проекта

webAppCreator -out stock-watcher name.webdizz.gwt.stock.watcher.StockWatcher

Note: прежняя схема создания GWT проектов для Eclipse с помошью комманд  projectCreator and applicationCreator устарела.

Создаем GWT проект
Создаем GWT проект

После создания проекта его необходимо импортировать в Eclipse.

“Import” -> “General” -> “Existing Projects into Workspace”

Continue reading GWT 1.7 on SpringSource dm Server 2.0.0.M3