Транзакции JMS и платформа SOA. (перевод, часть 4)

Продолжение. См. предыдущую часть.

Что еще потребуется базе данных в "быстром старте"? Сервис, создающий базу данных (JmsTransactedDatabaseInitializer), должен быть развернут (deployed). Это решается через файл deployment.xml (он создаст очереди JBoss Messaging, которые потребуются для "быстрого старта"):

1.<jbossesb-deployment>
2.<depends>jboss.esb.quickstart.destination:service=Queue,name=quickstart_jms_transacted_Request_esbdepends>
3.<depends>jboss.esb.quickstart.destination:service=Queue,name=quickstart_jms_transacted_Request_gwdepends>
4.<depends>jboss.esb:service=JmsTransactedDatabaseInitializerdepends>
5.jbossesb-deployment>

И в заключении, файлы jbossesb-service.xml и quickstart-ds.xml должны быть включены в архивный файл приложения .esb "быстрого старта". Это реализуется свойством "additional.deploys" в файле "быстрого старта" build.xml и файлом ../conf/base-build.xml, который используется во всех "быстрых стартах".

1.cat -n build.xml | grep quick
2.&lt;property name="additional.deploys" value="jbossesb-service.xml quickstart-ds.xml" /&gt;

ОК, с базой данных у нас все. Теперь давайте посмотрим, как настроить "быстрый старт", чтобы воспользоваться поддержкой транзакций со стороны SOA-платформы JBossESB. Как обычно, все начинается с файла jboss-esb.xml.

В файле jboss-esb.xml

01.xml version = "1.0" encoding = "UTF-8"?>
03.   
04. <providers>
05.   <jms-jca-provider name="JBossMessaging" connection-factory="XAConnectionFactory">
06. 
07.     <jms-bus busid="quickstartGwChannel">
08.       <jms-message-filter
09.         dest-type="QUEUE"
10.         dest-name="queue/quickstart_jms_transacted_Request_gw"
11.         transacted="true"
12.     />
13.     jms-bus>
14.     <jms-bus busid="quickstartEsbChannel">
15.       <jms-message-filter
16.         dest-type="QUEUE"
17.         dest-name="queue/quickstart_jms_transacted_Request_esb"
18.         transacted="true"
19.     />
20.     jms-bus>
21.     <activation-config>
22.       
23.       <property name="dLQMaxResent" value="5"/>
24.     activation-config>
25. 
26.   jms-jca-provider>
27. providers>
28. 
29. <services>
30.   <service
31.     category="JMSSecuredESB"
32.     name="SimpleListener"
33.     description="JMS Secured quickstart sample">
34.     <listeners>
35.       <jms-listener name="JMS-Gateway"
36.         busidref="quickstartGwChannel"
37.         is-gateway="true"/>
38.       <jms-listener name="jmssecured"
39.         busidref="quickstartEsbChannel"/>
40.     listeners>
41.     <actions mep="OneWay">
42. 
43.       <action name="printMessage" class="org.jboss.soa.esb.actions.SystemPrintln">
44.         <property name="message" value="JMS Transacted Quickstart entered. Message body"/>
45.         <property name="printfull" value="false"/>
46.       action>
47. 
48.       <action name="insertDBAction" class="org.jboss.soa.esb.samples.quickstart.jmstransacted.test.DBInsertAction">
49.         <property name="datasource-name" value="java:JmsTransactedDB"/>
50.         <property name="db-insert-sql" value="insert into jms_transacted_table(data_column) values(?)"/>
51.       action>
52. 
53.       
57.       <action name="throwExceptionAction" class="org.jboss.soa.esb.samples.quickstart.jmstransacted.test.ThrowExceptionAction">
58.         <property name="rollbacks" value="5"/>
59.       action>
60. 
61.       <action name="printMessageDone" class="org.jboss.soa.esb.actions.SystemPrintln">
62.         <property name="message" value="JMS Transacted Quickstart processed successfully. Message body"/>
63.         <property name="printfull" value="false"/>
64.       action>
65. 
66.       
67.       <action name="testStore" class="org.jboss.soa.esb.actions.StoreMessageToFile"/>
68.     actions>
69.   service>
70. services>
71. 
72.jbossesb>

  • Строка 2. - Прежде, чем мы пойдем дальше, мы должны посмотреть на XSD (XML schema definition) для файла jboss-esb.xml. Определение схемы доступно здесь: http://anonsvn.jboss.org/repos/labs/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd. Если вы хотите преуспеть в работе с SOA-платформой, будет хорошей идей ознакомиться с XSD, т.к. в нем все элементы для работы с файлом jboss-esb.xml. Двумя основными элементами являются, конечно же, провайдеры и сервисы. Давайте посмотрим сначала на провайдеров. Поддерживается два типа провайдеров.Планирование провайдеров определяется планированием слушателей, которые принимают сообщения из очередей (вы догадались). В отличии от провайдеров шин (bus providers), таких как jms-jca-providers, используемых в "быстром старте", тут нам нужно ассоциироваться со слушателями, которые принимают поставляемые им сообщения. [7]
  • Строка 5. - Вот начало нашего jms-jca-provider. Обратите внимание на то, что XAConnectionFactory предоставляет поддержку для распределенных транзакций.
  • Строки 7-13. -Это ссылка на канал и JMS очередь, которые будут использоваться, когда JMS сообщение будет отправлено в JMS-шлюз (JMS gateway), как заложено логикой "быстрого старта". На секунду остановимся и поговорим о том, в каком виде данные перемещаются в и через SOA-платформу JBossESB. Одной из главных функций, осуществляемых JBossESB, является маршрутизация сообщений между сервисами. (Я говорил об этом, и повторю это снова; запомните это, что в ESB все является либо сообщением, либо сервисом.) Сообщения, которыми оперируют JBossESB, являются org.jboss.soa.esb.message.Message. Конечные точки сервисов (service endpoints), которые могут управлять (process) сообщениями в этой форме, описываются как сущности "ESB-совместимые" ("ESB-aware"). Все это хорошо для сервисов и приложений, которые были разработаны и описаны в этом формате, но как на счет других сервисов, включая  приложения, которые были написаны давно и которые взаимодействуют посредством других, не ESB-совместимых форматов? JBossESB обрабатывает подключения сервисов, которые взаимодействуют посредством не ESB-совместимых форматов - через слушатели шлюзов (gateway listeners). Эти слушатели перенаправляют входящие сообщения от  источников за пределами ESB - к ESB-сервисам. Эти слушатели шлюзов у ESB-шин (как правило, они называются "шлюзами") -  поддерживают различные форматы сообщений, такие как файлы, FTP, и JMS. Эти шлюзы принимают сообщения в не ESB-совместимом формате  Эти шлюзы принимать сообщения в ESB не-известно формате на ESB, а затем преобразовать их (на самом деле, они обертывают первоначальные сообщения), перед отправкой их своим сервисам командных потоков сообщений (service's action pipeline).
  • Строка 11. - Помните, мы хотим, чтобы сервис обрабатывал сообщение, с поддержкой при этом транзакций.
  • Строки 14-20. - Шлюзы предназначены для того, что JBossESB общался со внешними источниками данных. Шлюзы сами по себе не перемещают данные по ESB. Таким образом, для каждого канала шлюза (Gateway channel), который мы определили - мы должны определить соотв. ESB-совместимый канал, который будет использоваться для маршрутизации сообщения в ESB.
  • Строка 21. - Определяем в ноде "activation-config" - как мы будем делать связь (link) с JCA. В этом "быстром старте" еще интересно свойство "dLQMaxResent". Как показывает комментарий в листинге - "DLQMaxResent" контролирует число попыток JCA-адаптера переслать это сообщение, перед тем, как очередь отправки остановит свою работу. Этот сервис JBossESB пересылает сообщение еще раз, в том случае, когда оно попало в очередь недоставленных сообщений. (JMS транспорт обычно имеет очередь недоставленных сообщений, т.к. JBoss Messaging поставляется с набором  преконфигурированных установок в destinations-service.xml, включающих в себя: < mbean code="org.jboss.jms.server.destination.Queue" name="jboss.messaging.destination:service=Queue,name=DLQ"). В этом быстром старте JCA-адаптер будет пытаться отправить сообщение 5 раз.
После того, как мы определили наши провайдеры, мы можем определить наши сервисы.

(продолжение следует)

Транзакции JMS и платформа SOA. (перевод, часть 3)

Продолжение. См. предыдущую часть.

Быстрый старт - в деталях

Транзакция в "быстром старте" включает себя две вещи - сообщение JMS и запись в базу данных. Давайте начнем с изучения подключения к базе данных HSQLDB, которая используется в "быстром старте". Во-первых, нам необходимо создать источник данных для определения подключения к базе данных.

В файле: quickstart-ds.xml:

01.<datasources>
02.<local-tx-datasource>
03.<jndi-name>JmsTransactedDB</jndi-name>
04.<connection-url>jdbc:hsqldb:hsql://localhost:1706</connection-url>
05.<driver-class>org.hsqldb.jdbcDriver</driver-class>
06.<user-name>sa</user-name>
07.<password></password>
08.<min-pool-size>5</min-pool-size>
09.<max-pool-size>20</max-pool-size>
10.<idle-timeout-minutes>0</idle-timeout-minutes>
11.<depends>jboss:service=JmsTransactedDB</depends>
12.<prepared-statement-cache-size>32</prepared-statement-cache-size>
13.</local-tx-datasource>
14. 
15.<mbean code="org.jboss.internal.soa.esb.dependencies.HypersonicDatabase"
16.name="jboss:service=JmsTransactedDB">
17.<attribute name="Port">1706</attribute>
18.<attribute name="BindAddress">localhost</attribute>
19.<attribute name="Database">JmsTransactedDB</attribute>
20.<attribute name="Silent">true</attribute>
21.<attribute name="Trace">false</attribute>
22.<attribute name="No_system_exit">true</attribute>
23.<attribute name="DataDir">${jboss.server.data.dir}</attribute>
24.</mbean>
25.</datasources>

Некоторые пояснения (исправил неточности, ниже. - Прим. перев.):
  • Строка 2. - Мы опеределяем local-tx-datasource так, чтобы можно было использовать JCA-подключение с поддержкой транзакций. [6]
  • Строка 3. - Мы используем JNDI-имя, для ссылки на этот источник данных (datasource).
  • Строки 5-13. - драйвер класса базы данных, соединение, URL, логин/пароль и т.д., для подключения к базе данных.
  • Строка 15. -Интерфейс MBean для работы СУБД Hypersonic в той же самой виртуальной Java-машине, в которой работает и JBoss. Запомним, что здесь у нас название сервиса, а так же JNDI-имя, все это нам скоро потребуется.
 ОК, у нас есть datasource, который нужен для подключения к базе данных HSQLDB, и это нам нужно в режиме поддержки транзакций. Что теперь? Мы должны гарантировать, что наша база данных на самом деле существует, прежде чем мы попытаемся ее использовать! К счастью, у SOA платформы есть класс, который может инициализировать базу данных при развертывании (deployed) .esb-приложения.

В файле jbossesb-service.xml:

01.<?xml version="1.0" encoding="UTF-8"?>
02. 
03.<server>
04.<mbean code="org.jboss.internal.soa.esb.dependencies.DatabaseInitializer"
05.name="jboss.esb:service=JmsTransactedDatabaseInitializer">
06.<attribute name="Datasource">java:/JmsTransactedDB</attribute>
07.<attribute name="ExistsSql">select * from jms_transacted_table</attribute>
08.<attribute name="SqlFiles">
09.hsqldb/create.sql
10.</attribute>
11.<depends>jboss.jca:name=JmsTransactedDB,service=DataSourceBinding</depends>
12.</mbean>
13.</server>

В этом файле есть несколько (3) интересных вещей:
  • Строка 4. - Этот MBean создается при запуске базы данных. Как его подключить к базе данных? Смотри строку 6.
  • Строка 6. - Это ссылка на наш datasource. Обратите внимание на JNDI-имя, которое мы определили в datasource. Как сделать, чтобы DatabaseInitializer знал, какую искать схему в базе данных? Смотри строку 9.
  • Строка 9. - Вот ссылка на файл из "быстрого старта" - src/hsqldb/create.sql. Этот файл создает очень простую таблицу в нашей базе данных, для использования в "быстром старте".
В файле src/hsqldb/create.sql:

1.create table jms_transacted_table
2.(
3.unique_id INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY,
4.data_column VARCHAR(255) NOT NULL
5.);

(см. продолжение)

Транзакции JMS и платформа SOA. (перевод, часть 2)

Продолжение. См. предыдущую часть.

Транзакции и SOA-платформа JBossESB

 OK, все это интересно, но выглядит так, как будто больше подходит для баз данных, нежели чем для сервис-ориентированной архитектуры. Как транзакционная модель соотносится с SOA-платформой JBossESB, в которой есть только сообщения и сервисы?

Вот как это выглядит: транспортный уровень платформы (InVM[3] и JMS) поддерживает транзакционную доставку сообщений. Фактическая доставка сообщения не произойдет, пока транзакция не будет зафиксирована. Как можно произвести откат транзакции в командном потоке сообщений (action pipeline)? Для этого нужно сконфигурировать приложение и его сервисы на использование транзакций, а затем вбросить исключение RuntimeException в командный поток сообщений. Лучшим способом объяснить и проиллюстрировать это - будет пример программы, который послужит "быстрым стартом" в SOA-платформу.

Быстрый старт

Одной из хороших особенностей SOA-платформы является постоянно развивающаяся база наработок простых примеров, "быстрые старты", иллюстрирующие ее различный функционал. Все это является хорошим ресурсом для создания собственных приложений. В нашем примере мы рассмотрим "быстрый старт", который называется "jms_transacted".

Данный "быстрый старт" иллюстрирует использование транспорта JMS в SOA-платформе JBossESB для обработки транзакций. "Быстрый старт" так же показывает обратное получение сообщений, на базе транспорта JMS. Прежде чем мы исследуем код "быстрого старта", конфигурационные файлы и получаемый результат, будет важным остановиться на использовании в "быстром старте" - JCA (Java Connector Architecture) [4].  JCA обеспечивает стандартизированный способ подключения к провайдерам JMS. В SOA-платформе JBossESB - JMS-JCA-провайдеры предоставляют поддержку транзакций командного потока сообщений, заключая их в JTA-транзакции[5]. Эти транзакции гарантируют обработку сообщений в пределах транзакции. Если что-то пойдет не так, сообщения будут помещены в очередь JMS для повтора операции. Мы увидим все это, когда запустим пример из "быстрого старта".

Последовательность действий в примере из "быстрого старта":
  • Как и во многих "быстрых стартах" по SOA-платформе, все начнется с JMS-сообщения, отправленного к сервису, что и послужит стартом командного потока сообщений.
  • При старте командного потока сообщений - в базу данных HSQLDB из "быстрого старта" - вставится новая строка. Обратите внимание, что для данного, полностью функционального примера - мы используем базу данных HSQLDB, хотя все полностью обеспечивается и для других баз данных, например и для MySQL, и для Oracle, и для PostgreSQL, и т.д.
  • Затем, для вброса исключения, мы используем класс org.jboss.soa.esb.samples.quickstart.jmstransacted.test.ThrowExceptionAction. Этот класс сконфигурирован так, чтобы 5 раз вбросить исключение, для принудительного осуществления отката транзакции (roll back), которая охватывает и запись в базу данных. Каждый раз, когда будет вкидываться исключение, JCA-адаптер будет осуществлять откат транзакции. Исключение так же распространится до самого JCA-адаптера и сообщение об ошибке запишется в лог.
  • После того, как будет достигнуто 5 сконфигурированных откатов транзакций, выполнит свою работу класс org.jboss.soa.esb.samples.quickstart.jmstransacted.test.DBInsertAction и транзакция зафиксируется в классе SOA-платформе JBossESB org/jboss/soa/esb/common/JBossESBTransactionService таким образом, чтобы конечным результатом стало помещение только одной строки в базу данных.
Теперь мы подробно рассмотрим, как сконфигурировать транзакцию и как все это будет выглядеть после запуска.

(см. продолжение)

Транзакции JMS и платформа SOA. (перевод, часть 1)

Оригинал статьи - "JMS Transactions and the SOA Platform".

При разработке программного обеспечение, в независимости от тщательности вашего планирования, неизбежны непредвиденные ситуации, предусмотреть которые вы изначально не могли, не помог в этом и ваш предыдущий опыт разработки. (Поверьте моему опыту. Я занимаюсь тестированием программного обеспечения и трачу большую часть своего рабочего времени на выяснение причин возникновения ошибок в программном обеспечении и их отладку). Так. как избежать ошибок все равно не получится, то ключевой особенностью дизайна системного программного обеспечения является способность к восстановлению после сбоев.

Классическим примером является ситуация с переводом денежных средств между банковскими счетами. Это 2-ух фазная операция. Сначала деньги снимаются с одного счета, затем деньги зачисляются на второй счет. Звучит просто, не так ли? Однако предположим, что система обнаруживает сбой после того, как деньги сняты с первого счета и прежде чем они были перечислены на второй счет. Что произойдет с деньгами? Как не потерять эти деньги? Ответ на этот вопрос в том, что вам нужно рассматривать оба эти действия - как одну транзакцию.

Транзакции и ACID-свойства

Что же такое "транзакция"? К сожалению, этим словом зачастую злоупотребляют в софтверной отрасли, как и многими другими. На самом деле транзакция представляет собой логическое объединение нескольких отдельных действий - в одно большое действие, при этом большое действие или выполняется, или не выполняется, по принципу - "все-или-ничего", оно расценивается как оценка выполнения совокупности всех отдельных действий, входящих в нее [1].

В вышеупомянутом примере перевода денежных средств - логическое объединение двух отдельных операций с денежными счетами в одну транзакцию будет гарантировать, что если не удастся выполнить денежный перевод, то ваши деньги не будут потеряны, и оба счета будут восстановлены в их первоначальное состояние.

Транзакции часто описывают в терминах "ACID"[2]-свойств:
  • Атомарность. Когда мы говорим об "атомарности" транзакции, мы имеем в виду, что транзакция, состоящая из нескольких отдельных действий - может рассматриваться только как одно атомарное целое. Если любое одно из этих отдельных действий не удается, как в нашем примере любая операция с одним из денежных счетов, то все будет отменено. (Термин, используемый для описания этого - "Откат транзакции" - "Roll back"). Транзакция - это конструкция "все-или-ничего". Транзакцию можно завершить (сделать "Commit" для фиксации транзакции), только при условии, что все отдельные действия, входящие в нее - завершились успешно.
  • Согласованность. Транзакция не может оставлять данные, которыми она оперирует, в неком несогласованном, промежуточном состоянии. Если транзакция откатывается, то и оперируемые ею данные должны вернуться в начальное состояние, которое у них было до момента начала транзакции.
  • Изолированность. В контексте транзакции ее изолированность означает, что любые данные из промежуточного состояния транзакции будут не видны, не доступны - для другой транзакции. Например если наш банковский перевод выполняется как одна транзакция, то пока она не будет завершена - другие процессы не смогут увидеть данные по каждой из совокупных операций, входящих в транзакцию.
  • Долговечность. При фиксации успешной транзакции данные должны быть должным образом сохранены, никакой аппаратный или любой другой сбой не должен вызвать потерю уже сохраненных данных. Тоже самое должно быть обеспечено при откате транзакции - данные должны быть так же надежно сохранены.
(см. продолжение)

JSF в финальном релизе JBoss AS6. (перевод)

Оригинал статьи - "JavaFX… does it have a future?".

JSF в финальном релизе JBoss AS6

Когда я создавал здесь блог, он был о JSFUnit. Но сегодня пришло время включить в него материалы и о других вещах, над которыми я работаю в JBoss. Помимо JSFUnit, я так же отвечал за интеграцию JSF в сервер приложений JBoss. С появлением финальной версии JBoss AS6, я бы хотел рассказать о некоторых больших улучшениях.


Короткая история о JSF в JBoss AS

JSF был интегрирован в JBoss AS, начиная с версии 4.0.3. В то время мы использовали MyFaces 1.1. В реальности это означало, что JSF должен был быть указан в пути к классам, поэтому вам не нужно было заниматься связыванием JSF с вашим WAR-файлом и т.д. Интеграция была на столько сырой, что вы должны были объявить слушателя событий контекста MyFaces - в вашем родном web.xml.

В JBoss AS4.2 и AS5 интеграция стала большей. Мы перешли на сановскую реализацию JSF 1.2, теперь известную как Mojarra.
JSF 1.2 включает поддержку аннотаций JEE 5, таких как @PostConstruct, @PreDestroy, и @Resource. Это так же включало интеграцию с JSP и EL. И уже не нужно было объявлять слушателя в web.xml.

Несмотря на лучшую интеграцию и новые фичи, некоторые люди были очень недовольны. Ведь несмотря на то, что MyFaces и Mojarra соответствовали одним и тем же спецификациям и проходили тестирование на одних и тех же тестах, они не были на 100% совместимы. И приложения, которые отлично работали на AS4.0.3 -  могли уже не работать на AS4.2 и AS5. Более того, реальность такова, что JSF приложения даже не полностью совместимы в рамках версий JSF. Приложения, которые работали на Mojarra 1.2, возможно не запустятся на Mojarra 2.

Я уж не говорю про библиотеку компонентов JSF. Там совместимость между версиями и их реализациями еще хуже.


JSF на AS6: к познанию реалий жизни

Реальность такова, что сервер приложений должен хорошо взамиодейстсовать с более чем одной реализацией JSF. Поэтому, в AS6 - мы поддерживаем три версии JSF.
Mojarra 2.0 сделана реализацией по умолчанию. Mojarra 1.2 - для облегчения миграции с AS5. И, MyFaces 2.0 - для тех, кто предпочитает MyFaces. Чтобы выбрать другой JSF, все что вам нужно сделать, это объявить один контекстный параметр в вашем web.xml, следующим образом:

<context-param>
    <param-name>org.jboss.jbossfaces.JSF_CONFIG_NAME</param-name>   
    <param-value>Mojarra-1.2</param-value>
</context-param>

Но описание возможностей этим не заканчивается. Например вы хотите связать JSF с вашим WAR-файлом таким образом, как это реализовано в Tomcat. Ну что ж, прекрасно. Если вы хотите добавить поддержку четвертой версии JSF к JBoss AS, и сделать ее по умолчанию, то это очень легко.

Вы можете связать библиотеку компонентов с конкретной версией JSF и назвать это "MyPerfectJSFConfig". После этого ссылайтесь к JSF Config в web.xml для всех ваших приложений, которым нужно это. И теперь вам уже не нужно снова и снова связывать jar-ы RichFaces или IceFaces, в каждом вашем WAR:
<context-param>
    <param-name>org.jboss.jbossfaces.JSF_CONFIG_NAME</param-name>   
    <param-value>MyPerfectJSFConfig</param-value>
</context-param>
Все это очень удобно для тестирования приложений с различными версиями JSF и их реализациями. Когда-нибудь спрашивали себя, будет ли ваше Mojarra-приложение работать быстрее (или без ошибок) на MyFaces? Теперь это легко выяснить. Что делать, если у вас есть старые приложения, которое работает на JSF 1 2, но у вас также есть новое приложение, которое работает на JSF 2.0? Вам не нужно беспокоиться, что обновление до JSF 2.0 сломает старые приложения. Они могут работать бок о бок в одном экземпляре JBoss AS без изменений.

Если вам нужны дополнительные детали по реализации этого, то можете посмотреть документацию JSF на AS6.


Все это и многое другое

Не могу не упомянуть, что все JEE-интеграции, которые вы ожидаете - у вас будут. Если вы используете JSF 1.2, то вы получите фичи EE5, такие как аннотации для управляемых компонентов. Если вы используете JSF 2.0, то вы получите фичи EE6, такие как Bean Validation.

Таким образом, я действительно горжусь интеграции JSF в AS6. Потребовалось много работы, чтобы получить этот уровень гибкости. И я могу честно сказать, что каждая жалоба на интеграцию JSF, которую я слышал по предыдущим версиям JBoss, теперь исправлена. Теперь вперед к JBoss AS7.

Не прощаюсь и спасибо всем,

Стэн

Есть ли будущее у JavaFX? (перевод)

Оригинал статьи - "JavaFX… does it have a future?".

Не знаю, бывало ли еще когда-нибудь, чтобы технология получила столько упреков, сколько получила их JavaFX на прошлой неделе (здесь, здесь и здесь). JavaFX стала технологией, которую уже просто модно ненавидеть. Это как бельмо в глазу, для разработчиков.

JavaFX была впервые представлена на JavaOne 2007 (три года назад). Многие предсказывали ей смерть еще до того, как вышла ее версия 1.0 в декабре 2008 г. и многие продолжают предсказывать ей это и сейчас.

Прошлая неделя была ознаменована двумя событиями - моим представлением JavaFX масштаба предприятия (Enterprise JavaFX) для сообщества "Силиконовая долина разработчиков на JavaFX" (Silicon Valley JavaFX JUG), и петицией Стивена Чина (Steven Chin), чтобы JavaFX стала open source проектом.

Хочу, чтобы меня в точности поняли - JavaFX далека от совершенства, она имеет свои проблемы (см. ниже) и сейчас решается, есть ли у нее будущее. Давайте сначала посмотрим на ее положительные стороны.

Положительные стороны

JavaFX Script - это очень мощный язык. И в самом деле, это DSL (Domain Specific Language) для создания функционально насыщенных пользовательских интерфейсов, в которых приложение работает под управлением виртуальной Java-машины, на клиентской стороне. JavaFX Script вначале кажется непонятным (как и любой другой новый изучаемый язык программирования), но поработав с ним некоторое время, ощущаешь его мощь и простоту использования. Функция связывания (binding) в JavaFX - очень сильно упрощает разработку интерфейса пользователя (UI), ведь при этом все изменения модели отслеживаются автоматически. Я работаю с JSF (JavaServer Faces) со времени ее создания и могу вам сказать, что использование JavaFX Script для создания пользовательского интерфейса, возможно, даже проще, чем использование JSF. И на стороне JavaFX-приложений - вся мощь виртуальной машины Java, это позволяет нам строить достаточно функционально насыщенные и сложные клиентские приложения.

Отрицательные стороны

Как мантру, для жилищного строительства все твердят: район местоположения, район местоположения, район местоположения. Мантра же JavaFX: развертывание (deployment), развертывание, развертывание. К несчастью, это то, с чем у JavaFX дела обстоят очень плохо. Так было у оригинальных Java-апплетов, это же унаследовала от них и JavaFX (которая должна была стать следующей технологией апплетов или апплетами 2.0). Иными словами, ничего практически не изменилось с 1995 года. Я не понимаю, почему Oracle (ранее Sun) не решила эту проблему. Я знаю, что в Oracle есть очень умные люди, которые могли бы решить ее давно.

В большинстве случаев она выглядит примерно так - вы кликаете на ссылку для запуска JavaFX -приложения, тем самым оно запускается как апплет в браузере. Давайте предположим, что у вас уже установлен Java плагин. Браузер зависает примерно на 5 секунд. После 5 секунд, или около того, вы увидите внутри пунктирной окружности логотип Java. Пунктирный круг движется вокруг логотипа, как бы показывая процент загрузка апплета. Печально то, что это всего лишь анимированный GIF, который не показывает реальный прогресс загрузки. Почему так трудно показать процесс, сколько фактически уже загружено?

После этого все идет еще более "интересно". Если вам повезет, вы увидите довольно устрашающее предупреждение безопасности (нужно нажать "да"), после чего появится приложение. Если вам не повезет, вы будете продолжать видеть анимацию загрузки (с логотипом Java внутри), пока не закроете окно браузера. Ничто другого не произойдет. Не будет сообщения об ошибке. Не будет объяснения причины, почему апплет не был загружен. Ничего. Если вы захотите узнать, почему апплет не удалось загрузить, вам придется запустить Java-плагин в консоли и смотреть на исключения / ошибки. Запустить консоль не так то просто. Попробуйте объяснить процесс запуска ее - не-разработчику. Желаю удачи. Также нередки случаи, когда апплет, который работал секунду назад - на следующем запуске уже не работает, по неизвестным причинам.

То, что я описал выше - является основной причиной теперешнего состояния дел у JavaFX. Развертывание - самая настоящая катастрофа. Если Oracle нужно знать, как должно работать развертывание, то это очень легко. - Достаточно взглянуть на Flash. Сделать максимально простым и прозрачным, как работает Flash-приложения. Вот и все.

Потребуется ли учить новый язык?

Некоторые люди говорят, что им не нравится JavaFX потому, что им придется изучить новый язык. Ну, это больше только одни слова. Во-первых, любой приличный Java-разработчик сможет выучить JavaFX Script примерно за 2 дня. А во-вторых, никто не жалуется на то, что они должны выучить новый язык (или язык сценариев) при использовании Flex, или Ruby, или Scala, или даже JSF. Чтобы что-то новое узнать, всегда нужно что-то новое изучить. Сегодня, если вы  разработчик "широкого профиля", то вы должны постоянно учить что-то новое.

Что могло бы быть лучше

Посмотрите на любую крупную конференцию Java в течение последних двух лет, и вы увидите, что по крайней мере есть одна сессия, которая посвящена JavaFX. Судя по блогосфере и Twitter - сообщество JavaFX растет. Люди размещают примеры, создают пользовательские компоненты и пишут к ним руководства по CSS (наверное имеется в виду, что все подобные технологии обычно скинезуются посредством CSS, пользовательские компоненты в JavaFX - тоже. - прим. перев.). Сообщество разработчиков есть. Люди пытаются работать с JavaFX, но ни одна организация по настоящему ее не используют. Во время зимних Олимпийских игр 2010 в Ванкувере на основе JavaFX была разработана история наград, но я сомневаюсь, что ее многие сейчас вспомнят. Совсем недавно MLB.com разместила фантазийное приложение о бейсболе. Вот и все.

Аргумент, что в JavaFX нет средства, служащим мостом между дизайнером и разработчиком - является одним из самых важных.

Инструменты для JavaFX сейчас разрабатываются. NetBeans имеет JavaFX Composer  (визуальный инструмент для создания макета JavaFX приложений). Exadel (моя компания) работает над Exadel JavaFX плагин для Eclipse. Сейчас мы нацелены на создание наиболее мощного инструмента разработки для JavaFX. Кроме того, IntelliJ недавно объявил, что теперь предлагает поддержку JavaFX.

Тот факт, что в JavaFX отсутствуют многие стандартные элементы управления - также является веским аргументом. Новые и более технически продвинутые элементы управления на самом деле разрабатывается группой Oracle JavaFX. Но, кроме того, чтобы помочь сообществу строить компоненты сторонних производителей, JavaFX должна быть с открытым исходным кодом.

JavaFX масштаба предприятия

Корпоративные приложения, такие как мультимедийные и интерактивные панели (dashboards) и другие, функционально и графически насыщенные элементы пользовательского интерфейса - являются очень хорошими кандидатами для использования в JavaFX. На самом деле сейчас нет применения JavaFX масштаба предприятия. Adobe и ее сообщество проделали отличную работу, продемонстрировав, что Flex может быть использован для создания приложений реального предприятия. То же самое должно произойти и для JavaFX. Чтобы обеспечить проникновение JavaFX в корпоративный сегмент - Exadel создала фреймворк Flamingo. Flamingo позволяет подключить пользовательский интерфейс (UI), написанный на JavaFX - к back ends предприятий (к серверной стороне вопроса - прим. перев.), в виде Java EE, Spring, и Seam. Я лично пытался достучаться до Sun, а затем до Oracle, для совместной работы над корпоративными инструментами для JavaFX, но, как вы уже догадались, никакого ответа я не получил.

Будущее?

Еще есть время, чтобы технология JavaFX стала успешной, но это время уходит. Во-первых, как можно скорее решить вопрос с развертыванием (deployment). Просто начать с нуля, не пытаясь исправить текущий механизм развертывания. Во-вторых, Oracle-у необходимо прояснить свои планы по поводу JavaFX (возможно на JavaOne 2010?) Если Oracle не хочет или не нуждается в  JavaFX, тогда сделать open source, и пусть сообщество управляет этим в будущем. Я думаю, у Oracle есть 6-12 месяцев для того, чтобы попытаться возродить JavaFX. Если ничего не произойдет к тому времени (что составит около 4 лет с тех пор, как технология была объявлена) наверное путь к JavaFX будет закрыт.

Мои 2 копейки (Оригинал - "My 2 cents" - прим. перев. :) ).