вторник, 28 июня 2011 г.

JavaME сдохла

Так можно сказать, если начать что-либо искать в сети по теме. 

На работе делаем приложение для мобильных устройств, в их числе и java ME. Была проблема с большой задержкой при Http запросах. Как и полагается система работает через Connector, т.е. соединение открывается методом Connector.open(url).

Потом из него открывается output или input stream.  После завершения работы потоки и соединение нужно обязательно закрывать, не то лимит будет исчерпан. На некоторых телефонах даже нормальное закрытие не помогает. Как я когда-то вычитал на форуме nokia нужно обнулить ссылки на потоки и соединение, затем вызвать Runtime.getRuntime().gc(). Затем Thread.sleep(50), т.е. включить сборку мусора и дать ему время (50 мс), чтобы он убрал за нами. И на большинстве нокий и самсунгов только после этого шаманства соединение возвращается в пул и приложение не будет зависать после 13 соединения (на всех телефонах, на которых была данная ошибка, объем пула составлял 13 соединений).

Со всей этой батвой приложение работает, но работает медленно. Данные скачиваются относительно быстро, а перед этим приложение долго простаивает, ожидая получить GPRS соединение.  Посовещавшись, решили попробовать сделать соединение через сокет. При старте приложения открывать сокет, гонять по нему данные к серверу и обратно, потом при завершении приложения закрываеть потоки и соединение. Пока вроде все получается, т.е. соединение открывается вызовом метода Connector.open("socket://127.0.0.1:9000); Открывается поток conn.openInputStream(). Открывается поток на запись conn.openOutputStream(); В него пишется запрос outputStream.write("GET / http/1.1\n\nHost:127.0.0.1"); Потом outputStream.flush(); Потом считываем с inputStream методом write. ... (Продолжение следует, наверное)

Первый подход к playframework.org

Удалось поработать с платформой play!. После питона с Django переход на Java оказался не таким ужасным благодаря возможностям play, а именно, компиляция кода на лету и возможность мгновенного наблюдения за результатом внесенных в код изменений и классный язык шаблонов. 

Проблему создал hibernate, в play 1.2 он представлен  версией 3.6, которая, как оказалось плохо работает с драйвером postgresql, если использовать иерархию классов на одной таблице. Короче, с play 1.2 не сраслось. Откатился на версию 1.0.3, в который включен hibernate версии 3.3.

Вторая проблема возникла, когда я к серверу попытался получить доступ по сокету. Он никак не хотел принимать мой запрос вида GET / http/1.1   Host: 127.0.0.1. Вопрос решился установкой модуля netty версии 1.0.6, который заменяет стандартный веб-сервер. Для этого в командной строке достаточно набрать play install netty-1.0.6  и запускать приложение с помощью команды play netty:run [название каталога с приложением внутри].

пятница, 13 мая 2011 г.

Ошибка на Youtube

Сегодня youtube.com мне выдал:

500 Internal Server Error

Sorry, something went wrong.

A team of highly trained monkeys has been dispatched to deal with this situation.

If you see them, show them this information:
G26W9qLA0cMTaZg-LFyaF2DnrAtOBBhCyBoFNNvUfyOYAbI5a8oORKoTwRVV iRtroRtSVQ3WkB5RxqCDiTKPWWfnlDzUUpZOkNTh5m4RiGG_16Ci7imTNLEw eShN3h9tiyYtz7NbKgVjBYvrv696-tAXfCEPgMFs2XvlpwJn9NlN68pEMDAP wks8KmOKu8A64NjORSNWw8RnItLdb4YxWcY5J_VhzJLwONnHyEY2V5nxFxOU uHT0gPPnTYwNaXZSIJlWo5s5zyG-s3Z3ADECuAbg3yNSyE1Cw52Jalf5gAaX Uz3F04-YVF3zJGgjta0OVG2kNasj4yZ_clR0PPzuJWXJ8wi6CmLyxP5QOl_x DsY15LipdW2wfvlUBxaZDPmXLT8EFcUux5H4UHvq1ZYJDKVCJrthald0HRZw Q4X-WDK6hqNu1tU8SBGLVPxiKjOmVamByDoE94WkpmHmNNbvX_yGZkj5BCBh pK_jw0v5bdz9wORIym5VyvBFSfwEIle5_lm_RWd1A2fR4wC-b-TtCkAc-jMs GYtXIAHaFPWialGbVb9aEhbz8-Jth_dpQ3JQH2cXHv7IK_fpGoihgBaIyX5s 7k_GUXiiVb6_zen2RLBKemtExrmW_U_ZNxm0D2MNJiLe4q7g6Ckpmtjld4G8 mecjGssc3jB9FaRIVcCE_p0BN7ZYrs6xp1NCqDEBFrTG43dy3H_3HKEkCirC D9pu2iPmgcaWGCgc8LUF7dichy4C-4wTuWBTrx1CXNvWNpydHG2Uvb6sAcZV 433maYyMXmT2Rgcx_ax-6kd0URQAqvlwc6h65rSGDGGxKS5Ewhxaxuzgqa45 YwDvoYkwBQTXC8DcYok9qfyvB2aCWrFE5jWKi999ydSUO0r6Dsv6qW6hC95h 01aU0XYfD2bwFamGPpTFqFsHkRh5JlutfA3k5XwSaPzDbplpOookZlWNAvrI -_0wbtWmPIZv-BbWuGTV1WGISkhief1UxmEq1Z01WHPzbKhLFxwcdRkc5xXf WaBDWh_rcdklQYqDCbeO3ie4OZADKgTNH8LZw5V6qjOBJEFzQLUBxg1xkD5Z -kMTsKnC8eXup90fK90vaEOCp_RPMkal61hg0aEWsekzGLquq1NMoS7GcXy5 VHD-dN28wXY7no5Ovxij-HSSyScFLKEtVWigMKyAhgdzhJge2pwDDz9I3w5- H5oT3fW0ZEk6hmvLhxuVumTpjklORNolt5FJlcBtVSwMiAVHoiAdw1VtVz3r b9Bkw34xMcJcWWIgb1SVe36G7VOHn1iN9D5Pe-RJYZuH3OA6wgj_9CmDHQxK QelHDJywiBR_EyVvMJHJGyn_dZauPBLgMGPLcilCiLP3WgQCFaeV7_py2Nq5 p82lfHc0hlP5nrTM7Nvb23IjvOiyeiXvdmG7mBI18nRUxuvgJWSeRzrBIwmC Ku77uSKxcH4YV8cJu2OoNuu72GvMrtGrlO4shvGSp_CLAASP7SxphmD6xa6i wsEHenrRKynYctEygIgq9DFDVHU6XJ7RYPpaFaLGVaV57_cKl-jd6zSHhV9P dd3d-E5ovcGFN297EM9kQvjK0BHVDLsUoEgNahh2FQDcaue00Xh_GBeExmD8 bnLeuAAvv8cmgFldon3Ht0VCZAgXsHUXJAcCH7bVG39GMMsLiHfZkVr0FaGS dGDeigZmoo_plHVkt2UPByP2ncm4dhaFxdl8a4EzZZ2qrHsduc1w1eqH8JpL wo3ZAU09-zPmnWGOgDz4LPctgQzSooQMNL0CmMM1107tDG2PE-9VZkfqPlap jKlgIJnLzzZGbwW12MyZzUKViKYtovwFfhR1idfkJeJHvRCkrKJKcY40LMpQ b8P7urfJn7LJJovFq3Z9XmOT4Uona6Ra_Er9CkG3ZtIhNp3Ot3oRlqZlbetp sj4HTz-_XmIkHPTL257OuOjwIapWe4g1V2_2D1O4Q_AV-Ez13NoUkiMvLSFZ OMXLrhnxJadmYZvx1HecXgVJYDkiepyE_aajo6uzmHXIvFPqW2LWgGIYy82b xentz762GGbRc_Vglw2fGb9E2vAEASKNrv1qy8yLs_WgLNpGDWnAL47oiFX6 sm1vEE8FVf7pCPFRVR7yX10ETp0Ty-9XSxgsrF0ru7AdbXtxmCD5mf5r3Uxt S-ZNhPCNU3Eumz8ySAUv5NYKsoQTKoELfgJvp-tjdEYZkRnIQEWUNwN0MCjX knqZb8t-wwiEemCNaz3_3Byt3GVlCXZc_TRQWNZJ4-WB3oEtq5TF37dUTkG8 T1w969dVhf88nqX7pTBNS6YuDM1nr4D8o_YDZgHMojfjr99DEEP2QEiUehwa 2vIuDuYdSZLbspTyh7IZDx_p9jfxt-pFoBNOrU2Ivmm6E21XQ-ZmXMhl-wl0 C3veLY8RPR8MpJmQnixap0sNfNemG1ianaqNb_hGeT5MrJFhcRMwzKA1wlBE 70Lxs1EU1WKN-RsN3qoHKRuwpws4XEo3skcYX8YWsLgi88vPArHUH8LWvX3c MnmuCvEjckotEN6mfbjNYrsZEK4285aKHgKZBmvDL4iODdENWCVrxQGEsoCP U6J_rsoStuqwNe511nip0G9-ChE_cKAED0g_dfAJcChw5rlYCPQmVcDnNCsu Ex0JPAWxWbsraLfhDOGmbmrE9eJSQXV4I75kV-4DiZlvFfktCXBRdAtMFvxT Keq5nnjKsXWCwdurMA3xDEC-mTnaoCZibqD0EmuT_c7oP5HwgdXiQwxXgDBo Xj3_i_n04ZHstcxZZP2uhvFM3DX-D0_StKFZShxwH4RJHX2g25NcG1ubK7Dx 7K-2m8Pi0FKQ91GhSEIcUkuLSkWKvzhhNOhEobt0PWqboos1gu-1xG9VfWwa 0-eTxT_sM5Q09nK_7954jdbkvSz6lItUyzzxMyFLEVrX0iepoaUQnuIh4sjF eQGO99R35WafavnrgYG0fZfl5k1bMMfI3iSaXQ-93BtiWnK71XKnSfYAQQmq 1ruZagMBLKUtAncPndphSK3NFW6Q6MQsQGaDE_g4JjRSa_1AYR7j0gVy3x0X stok2JyNM9kUd5i4hsuQfkTjJMGw2iRtQjLlGyXFZZbCy_1AlwHeUGY1D-ni -rTVp1WiDVtuVEgDnwkumyTU27_laaI-Vcd1nPqwNcfN-w3fVk7BA-L_riox xhv8P81sTIwdOZ9Ib06KaHxTqCAnxQoQXp6ETk2TOx5sN11_X5n_sKBeWwma TKUs-t8OyKOX3llMWFGZpI3_rrIbHk6YbS8MM4IcUrbsM6aQzAYgQzReaOfS 0oJdQD4o5sfPTkCZ9sl50guMvIhxmvkWSR6bNcGdRleIe3k8Bt6OQZ-sl5nC OzXH0Y61m08Cob9N_2D-2CC_X2rU6eakycea3BCZsdMPEd8G8F4iERXjNnzd 6VFLML2Rsj2Q5BG4ovdX5PoAOzec6EqmCjqXdd99Q050XxQLQjctn9k3EbAn ls8SqByRBLhObZOPbytev7KksKW6JoFRiSNivLJaqFSeLgxS_ZKQ4_PDMAlq XhpJIl0ANJcKbK3d9dqhzc8lDE_Mvyx6Zmj1uIJJc5R4KO77gBynyKLHe0Ej 48WL-PaR_tP-asGwvqGaeLp_K6rMYie9cuALhYuzdkBUvW7GMFzmTLVCeik=

пятница, 11 марта 2011 г.

Выключение второй видеокарты на acer timelineX 3820TZG

Добрый день!

Недавно купил себе большой нетбук - Acer Aspire TimelineX 3820TZG. Поставил на него Ubuntu 10.04 (64 bit). Все вроде как классно, но ноутбук сильно греется и батарейки хватает всего лишь на 4 часа. Поискав на форумах, обнаружил такую штуку. Это модуль для ядра, который при помощи acpi вызовов позволяет включать и выключать вторую (не встроенную видеокарту).

На сайт linux-hibrid-graphics автор поста предлагает скачать исходники, собрать их командой make. Затем набрать sudo insmod acpi_call.ko. Затем запустить тестовый скрипт test_off.sh.

Описанный способ я обнаружил только потом, и уже успел добиться того же результата с помощью:

make sudo cp acpi_call.ko /lib/modules/`uname -r`/kernel/ 
sudo depmod
echo acpi_call | sudo tee -a /etc/modules > /dev/null

суббота, 29 января 2011 г.

Про установку Redmine

Решил сегодня поставить Redmine (http://www.redmine.org). До этого пользовался Trac.
Redmine кажется круче (по крайней мере по количеству кнопок на главном окне :) )

Установка системы хорошо описана.

Долгое время не мог сделать мигрейт на базу данный с команды rake db:migrate RAILS_ENV=»production». Rake все время ругался на ошибку синтаксиса в файле config/database.yml. Проблема, оказывается, была в том, что я в вим поставил табы вместо нескольких пробелов. После замены все заработало.

Compojure 0.6.0

Я пропустил объявление о выходе новой версии библиотеки Compojure - http://groups.google.com/group/compojure/browse_thread/thread/4f8574d808ddf53e.
Теперь он поддерживает контексты.

пятница, 21 января 2011 г.

Начало проекта с Scala, Vaadin и Circumflex ORM

Решил написать простенькое приложение на Scala с использованием Vaadin и Circumflex ORM.
Запустил Netbeans. Создал maven проект с Simple Vaadin Application archetype. Для теста запустил. Выключил. Полез в гугл за ответом на вопрос "как в приложение java внедрить scala". Нашел работающее решение на http://stuq.nl/weblog/2008-11-26/4-steps-to-add-scala-to-your-maven-java-projects. Взял конфиг, который умеет обрабатывать циклические ссылки со скалы на java и обратно.
Затем написал тестовый класс на scala.


import com.vaadin.Application
import com.vaadin.ui._
import ru.circumflex.orm._
import com.kitprof.soma.entity._


class MyVaadinApplication extends Application {

def init = {
val window = new Window("My Vaadin Application")
window.addComponent(new Button("Click Me"))
setMainWindow(window)
}
}


Все прекрасно работает.

Теперь мне нужна база данных. Для разработки, я думаю, подойдет и h2 (Легкая, быстрая СУБД). Открываю pom.xml и добавляю


        com.h2database
        h2
        1.3.149

В качестве ORM я решил попробовать Circumflex ORM. Для этого в pom.xml пишу


        ru.circumflex
        circumflex-orm
        2.0.RC3
    

Circumflex для работы требуется файл с настройками cx.properties. Его нужно создать вручную в папке src/main/resources. В моем случае он имеет следующее содержимое:
orm.connection.driver=org.h2.Driver
orm.connection.url=jdbc:h2:~/test
orm.connection.username=myuser
orm.connection.password=mypassword
Значения всех параметров, я думаю, интуитивно понятно.
В моем приложении будут пользователи. Они должны иметь возможность авторизоваться, поэтому мне нужно, как минимум, два поля: логин и пароль. Итак,


import ru.circumflex.orm._

class User extends Record[String, User]{
val login = "user_login".VARCHAR(50).NOT_NULL
val password = "user_password".VARCHAR(50).NOT_NULL

def PRIMARY_KEY = login
def relation = User
}

object User extends User with Table[String, User]

Теперь мне нужно создать в базе таблицу users с полями user_login и user_password. Как и любая серьезная ORM тулза, Circumflex умеет сам создавать схему базы данных. Для меня самым удобным представился вариант через написание кода, поэтому в методе init класса MyVaadinApplication я добавил следующие строки:

    val ddl = new DDLUnit(User)
    ddl.DROP_CREATE

Метод DROP_CREATE каждый раз удаляет и создает схему заново. При разработке приложения, когда поля и свойства полей (такие как длина) часто меняются это очень удобно. Однако при тестировании удобно, когда в базе уже есть некий набор тестовых данных. Например, в моем случае не плохо было бы иметь несколько пользователей и не создавать их каждый раз после регенерации схемы базы данных. Для меня самым удобным представляется вариант создания некоего класса Bootstrap (привет liftweb.net), где будет код вида
 if (usersCount == 0) createTestUsersPlease()
Да, кстати, нужно попробовать запустить приложение, нажимаю Run и вижу, что все работает. H2 при этом создает в пользовательской папке файл test.h2.db (помните параметр orm.connection.url).

вторник, 18 января 2011 г.

Несколько часов возился с EJB 3.1.
Создал банальный бин UserEjb.

@Stateless

public class UserEjb{



@PersistenceContext(unitName="EjbPU")

private EntityManager em;


public User findById(Long id) {

return em.find(User.class, id);

}


public User create (User user){

em.persist(user);

return user;
}



public User findByLogin(String login){

return (User) em.createQuery("select user from User as user where user.login = :login").setParameter("login", login).getSingleResult();

}


public User edit(User user){

em.merge(user);

return user;
}

}

В классе vaadin он никак не хотел создаваться с помощью аннотации EJB, хотя все сделал как указано в из примере На сайте ваадин

В итоге пришлось написать такой код:

UserEjb userEjb = (UserEjb) new InitialContext().lookup("java:module/UserEjb");

четверг, 6 января 2011 г.

Rails на Clojure

По адресу https://github.com/macourtney/Conjure проживает Rails подобная библиотека для разработки веб приложений на языке Clojure. Из ее особенностей хочется отметить:

1. В качестве слоя доступа к базе данных (ActiveRecord в Rails) используется библиотека clj-record. Это позволяет удобно писать зависимости между сущностями бд, почти как в ActiveRecord, в стиле has_many, belongs_to.

2. Может работать на Google AppEngine. Для этого при создании проекта достаточно набратьlein conjure new -database google-app-engine. А затем с помощью lein uberwar создается веб архив.

3. Удобная работа с Ajax.

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