Jython-консоль вашего приложения
Расскажу вам как я использую интерактивную консоль Jython для ускорения разработки Bean’ов в поддерживаемом мной приложении.
Суть вопроса
Каждый кто хоть раз сталкивался с долго разрабатывающимися Java-приложениями, знает, что многие из них очень медленно собираются и стартуют. Не будем обсуждать почему так получается. Это тема отдельной статьи.
По долгу службы пришлось поддерживаю очень древнее приложение с громадной кодовой базой. Хуже всего то, что оно собирается оно от минуты до семи и ещё минуты три стартует. Опять же каждому программисту не сложно представить себе какой ад написать энное количество кода, а затем ловить NullPointerException’ы от внешних сервисов с таким длинным циклом Implement->Compile->Start Deploy->Wait->Smoke->Wait->Test.
Возможен также другой вариант. Есть энное количество кода в классе, который нужно адаптировать под выполнение задачи, близкой уже им выполняемой. А теперь представьте, что этот класс реализован в рамках Java 1.4. Он не работает с Generic’ами, потому что они были добавлены только в Java 1.5. Кроме того программисты, ранее занимавшиеся поддержкой системы, этим активно пользуются и суют в коллекции возвращаемые методами других классов, что не попадя вплоть до анонимных реализаций java.lang.Object.
Поев кактус пару дней я почувствовал, что начинаю сходить с ума от того, что пишу пять-двадцать строк работающего кода в день.
Способом ускорения разработки в таких варварских условиях я усмотрел только вкрутить в приложение интерпретатор какого-либо динамического языка для быстрого прототипирования уязвимого к таким условиям кода сначала на нём, а потом реализации алгоритма на Java. Конечно же в рамках решение нужна была ещё и интерактивная консоль этого языка. Какая же без этого динамика? Консоль хотелось в не в апплете из-за того, что апплеты очень плохо работают(скажем так, они просто не работают) во FreeBSD, к которой я очень уж привык в последнее время.
Поиск существующих решений
- Beanshell — отброшен по причине убогости телнет-консоли, поставляемой из коробки вместе с интерпретатором. Апплет не подходит.
- JRuby — отброшен по причине не того, что я обнаружил, что успел благополучно забыть этот язык с тех пор, как игрался с Rails во времена первой вспышки его популярности. Быстрое гугление не дало результатов кроме каких-то Corba-монстров. Испугался и закрыл.
- Groovy
Что-то похожее на то, что хотел нашёл у Sakai. Реализовано в качестве Spring Bean’а, а у нас свой Dependecy Injection-фрэймворк с блэкджеком и шлюхами. Не попробовал.
Jython
Python-программистам хорошо известна одна из его концепций «batteries included», что означает много разных вкусных библиотек даже в стандартной поставке. Только у Java свои батарейки. Реализация Python для JVM просто эталонная, а вот библиотеки пока портированы не полностью(например setuptools начал устанавливаться в Jython-окружении совсем недавно), так что у меня не получилось завести родные Python-решения.
Попробовал RPyC с разными версиями Jython(ночь прошла незаметно). Почитал про Twisted Manhole. Решил не сливать исходники тестовой ветки интеграции с Jython, потому как была опасность начать фиксить Twisted для Jython и стать после этого холостяком.
Собрал github.com/EnigmaCurry/jython-shell-server и понял: нет readline, нет счастья. Telnet не поддерживает readline, если разработчик не реализовал эту функциональность на серверной стороне. Представьте, что написали строку длиной в символов в 80 и вспомнили, что первый объект называется по другому. Конечно можно торкать мышкой в консоль, но хотелось родной похожей на bash-среды.
Моя реализация
Сервер
За пять минут выбрал XMLRPC в качестве интерфейса сервера. За следующих пять минут не передумал. За следующих 20 минут реализовал.
Код сервера на Jython:
from SimpleXMLRPCServer import *
from os import path
from code import InteractiveConsole as BaseInteractiveConsole
class Stdout ( object ) :
«»»Замена stdout для буферизации вывода в строку»»»
def __init__ ( self ) :
self . buffer = »
def get_buffer ( self ) :
«»»Получаем накопленный буфер и сбрасываем его»»»
bc = self . buffer
self . buffer = »
return bc
def write ( self , bs ) :
«»»Пишем в буфер вместо стандартного вывода»»»
self . buffer += bs
return len ( bs )
class InteractiveConsole ( BaseInteractiveConsole ) :
«»»Интерактивная консоль, возращает вывод выполнения команды»»»
def __init__ ( self , locals ) :
«»»Принимаем контекст выполнения консоли»»»
BaseInteractiveConsole. __init__ ( self , locals )
#Заменяем стандартные потоки собственной реализацией
self . stdout = sys . stdout = sys . stderr = Stdout ( )
def push ( self , line ) :
result = BaseInteractiveConsole. push ( self , line )
return ( result, self . stdout . get_buffer ( ) ) #Возвращаем вывод вместе с результатом
class Server ( SimpleXMLRPCServer ) :
«»»XMLRPC-сервер, поставляющий в сеть методы интерактивной консоли»»»
def __init__ ( self , ls, * args, ** kwargs ) :
SimpleXMLRPCServer . __init__ ( self , * args, ** kwargs )
self . register_introspection_functions ( )
#Регистрируем экземпляр консоли как обработчик с передачей контекста
self . register_instance ( InteractiveConsole ( ls ) )
Клиент
В качестве базового интерфейса был выбран Cmd, который из коробки поддерживает readline, что нам и нужно.
Код сервера на этот раз на Python(похоже Cmd в Jython не поддерживает readline):
from cmd import Cmd as BaseCmd
from code import InteractiveConsole as BaseInteractiveConsole
import re , sys
from xmlrpclib import ServerProxy
class Cmd ( BaseCmd ) :
«»»Реализация прокси-консоли»»»
reg = re . compile ( ‘^ \s *’ )
def __init__ ( self , host, port ) :
BaseCmd. __init__ ( self )
self . s = ServerProxy ( ‘http://%s:%d’ % ( host, int ( port ) ) ) #Клиент нашего сервиса
self . prompt = ‘>>> ‘ #Приглашение к вводу
self . leading_ws = » #Переменная для ведущих пробелов
self . is_empty = False #Переменная определяющая пустую команду
def precmd ( self , line ) :
«»»Тестируем различные условия с сырой строкой,
которая затем фильтруется»»»
#Сохраняем ведущие пробелы, т.к. они фильтруется при передаче в default
self . leading_ws = self . reg . match ( line ) . group ( 0 )
#Пустая ли команда, т.к. пустая команда далее преобразуется в повторение предыдущей
self . is_empty = ( line == » )
return line #Выполняем контракт, описанный в документации
def default ( self , line ) :
if ( self . is_empty ) : #Восстанавливаем пустую строкy
line = »
line = self . leading_ws + line #Восстанавливаем ведущие пробелы
( result, output ) = self . s . push ( line ) #Выполняем строку в удалённой консоли
#В случае если требуется новый ввод устанавливаем соответствующее приглашение
self . prompt = ( ‘. ‘ if result else ‘>>> ‘ )
sys . stdout . write ( output ) #Пишем аутпут в аутпут 🙂
if __name__ == ‘__main__’ :
HOST, PORT = sys . argv [ 1 : ]
Cmd ( HOST, PORT ) . cmdloop ( )
Java-обёртка для сервера
Простой Bean для запуска нашего сервера. Проще просто некуда.
package net.rjyc ;
import org.python.util.PythonInterpreter ;
import java.util.* ;
public class Server < private PythonInterpreter i ; public PythonInterpreter getInterpreter ( ) < return i ; >
public Server ( String host, int port ) < this ( host, port, new HashMap < String, Object >( ) ) ;
>
public Server ( String host, int port, Map < String, Object >locals ) < i = new PythonInterpreter ( ) ; //устанавливаем аргументы в экземпляр интерпретатора i. set ( «host» , host ) ; i. set ( «port» , port ) ; i. set ( «ls» , locals ) ; >
public void start ( ) < //запускаем сервер интерактивной консоли i. exec ( «from rjyc import Server; Server(dict(ls), (host, port), logRequests = False).serve_forever()» ) ; >
>
Использование
Предствьте себе гипотетический сервлет, который выводит список ссылок из своего поля.
Вот, что нам отвечает вебсервер:
siasia@siasia ~ % wget http://localhost:8080 -O - 2>/dev/null Python Java
Теперь внедрим в него нашу консоль.
И подключимся к ней:
siasia@siasia ~ % python client.py localhost 8081 >>> this examples.Hello@13ebc5c >>> this.links >>> this.links['Scala'] = 'http://scala-lang.org' >>> this.links
Проверим результат:
siasia@siasia ~ % wget http://localhost:8080 -O - 2>/dev/null Scala Python Java
Maven
-
Добавьте репозиторий в свой pom.xml:
Rjyc Repository http://siasia.github.com/maven2
org.python rjyc 1.0-SNAPSHOT
Solvusoft: Microsoft Silver Certified Company
Компания Solvusoft имеет репутацию лучшего в своем классе независимого поставщика программного обеспечения,
Microsoft признал Solvusoft в качестве ведущего независимого поставщика программного обеспечения, который достиг максимального уровня компетентности и совершенства в разработке ПО. Тесные отношения Solvusoft с Microsoft в качестве сертифицированного серебряного партнера позволяют нам предлагать лучшие программные решения в своем классе, оптимизированные для работы на устройствах с операционными системами Windows.
How is the Silver Competency Level Attained?
To achieve a Silver competency level, Solvusoft goes through extensive independent analysis that looks for, amongst other qualities, a high level of software expertise, a successful customer service track record, and top-tier customer value. As a Silver Certified Application Developer, Solvusoft is able to provide the highest level of customer satisfaction through delivering top-level software and service solutions, which have been subject to a rigorous and continually-audited approval process by Microsoft.
Jython – Обзор
Jython – это реализация JVM языка программирования Python. Он предназначен для работы на платформе Java. Программа Jython может импортировать и использовать любой класс Java. Как и Java, программа Jython компилируется в байт-код . Одним из основных преимуществ является то, что пользовательский интерфейс, разработанный в Python, может использовать элементы графического интерфейса AWT , Swing или SWT Package .
Jython, который начинался как JPython, а затем был переименован, тесно следует стандартной реализации Python под названием CPython, созданной Гвидо Ван Россумом . Jython был создан в 1997 году Джимом Хугуниным . Jython 2.0 был выпущен в 1999 году. С тех пор релизы Jython 2.x соответствуют эквивалентным релизам CPython. Jython 2.7.0, выпущенный в мае 2015 года, соответствует CPython 2.7. Разработка Jython 3.x находится в стадии разработки.
Разница между Python и Java
Ниже приведены различия между Python и Java –
- Python – это динамически типизированный язык. Следовательно, объявление типа переменной не требуется. Java, с другой стороны, является статически типизированным языком, что означает, что объявление типа переменной является обязательным и не может быть изменено.
- В Python есть только непроверенные исключения, тогда как в Java есть как проверенные, так и непроверенные исключения.
- Python использует отступы для области видимости, в то время как Java использует соответствующие фигурные скобки.
- Поскольку Python является языком интерпретатора, он не имеет отдельных этапов компиляции. Однако Java-программа должна быть скомпилирована в байт-код и, в свою очередь, выполняется JVM.
- Python поддерживает множественное наследование, но в Java множественное наследование невозможно. Тем не менее, он имеет реализацию интерфейса.
- По сравнению с Java, Python имеет более богатые встроенные структуры данных (списки, диктанты, кортежи, все является объектом).
Python – это динамически типизированный язык. Следовательно, объявление типа переменной не требуется. Java, с другой стороны, является статически типизированным языком, что означает, что объявление типа переменной является обязательным и не может быть изменено.
В Python есть только непроверенные исключения, тогда как в Java есть как проверенные, так и непроверенные исключения.
Python использует отступы для области видимости, в то время как Java использует соответствующие фигурные скобки.
Поскольку Python является языком интерпретатора, он не имеет отдельных этапов компиляции. Однако Java-программа должна быть скомпилирована в байт-код и, в свою очередь, выполняется JVM.
Python поддерживает множественное наследование, но в Java множественное наследование невозможно. Тем не менее, он имеет реализацию интерфейса.
По сравнению с Java, Python имеет более богатые встроенные структуры данных (списки, диктанты, кортежи, все является объектом).
Разница между Python и Jython
Ниже приведены различия между Python и Jython –
- Ссылочная реализация Python, называемая CPython, написана на языке Си. С другой стороны, Jython полностью написан на Java и является реализацией JVM.
- Стандартный Python доступен на нескольких платформах. Jython доступен для любой платформы с установленной JVM.
- Стандартный код Python компилируется в файл .pyc , а программа Jython компилируется в файл .class .
- Расширения Python могут быть написаны на языке Си. Расширения для Jython написаны на Java.
- Jython действительно многопоточный по своей природе. Однако Python для этой цели использует механизм Global Interpreter Lock (GIL).
- Обе реализации имеют разные механизмы сборки мусора.
Ссылочная реализация Python, называемая CPython, написана на языке Си. С другой стороны, Jython полностью написан на Java и является реализацией JVM.
Стандартный Python доступен на нескольких платформах. Jython доступен для любой платформы с установленной JVM.
Стандартный код Python компилируется в файл .pyc , а программа Jython компилируется в файл .class .
Расширения Python могут быть написаны на языке Си. Расширения для Jython написаны на Java.
Jython действительно многопоточный по своей природе. Однако Python для этой цели использует механизм Global Interpreter Lock (GIL).
Обе реализации имеют разные механизмы сборки мусора.
В следующей главе мы узнаем, как импортировать библиотеки Java в Jython.
Jython
Jython — это реализация языка Python на языке Java. Первоначальное имя проекта — JPython, которое пришлось поменять из-за конфликта с одноименным проектом (имя было занято на хостинге sourceforge.net), одновременно и компилятор, и интерпретатор.
Программы, выполняющиеся в среде Jython могут одновременно использовать классы языков Java и Python, используя, например, классы стандартной библиотеки Swing.
Разработка web-апплетов [ править ]
На языке Java можно разрабатывать апплеты для веб-браузеров. Но в настоящий момент апплеты в Jython не включены. Компилятор был удалён из пакета Jython 2.5.0 с целью внедрения новой технологии, которая лучше реализует создание апплетов. Технология будет включена в другую версию в ближайшем будущем. [1]
См. также [ править ]
Примечания [ править ]
- ↑Applets and Java Web Start (англ.)
- Найти и оформить в виде сносок ссылки на авторитетные источники, подтверждающие написанное.
- Дополнить статью (статья слишком короткая либо содержит лишь словарное определение).
Вы можете помочь проекту, расширив текущую статью с помощью перевода.