суббота, 25 июня 2011 г.

Установка Tomcat под Ubuntu

Для начала установливаем openjdk вместе с пакетом ubuntu-restricted-extras:
sudo apt-get install ubuntu-restricted-extras
установленная версия: 1.06_22

качаем томкат:
wget http://apache.cyberuse.com/tomcat/tomcat-7/v7.0.16/bin/apache-tomcat-7.0.16.tar.gz

распаковываем:
tar xvzf apache-tomcat-7.0.16.tar.gz

копируем в нужную папку:
sudo mv apache-tomcat-7.0.16 /usr/local/tomcat

также необходимо прописать переменные окружения JAVA_HOME и JDK_HOME. Для этого добавляем в файле /etc/environment:

JDK_HOME="/usr/lib/jvm/java-6-openjdk"
JAVA_HOME="/usr/lib/jvm/java-6-openjdk"

запускаем томкат:
sudo /usr/local/tomcat/bin/catalina.sh start

редактируем server.xml:
sudo nano /usr/local/tomcat/conf/server.xml

ищем следующий текст:

меняем порт на стандартный для http - 80, и указываем кодировку для URI:

создаем файл автозагрузки
sudo nano /etc/init.d/tomcat

и вставляем следующее:
# Tomcat auto-start
#
# description: Auto-starts tomcat
# processname: tomcat
# pidfile: /var/run/tomcat.pid

export JAVA_HOME=/usr/lib/jvm/java-6-openjdk

case $1 in
start)
       sh /usr/local/tomcat/bin/startup.sh
       ;;
stop)  
       sh /usr/local/tomcat/bin/shutdown.sh
       ;;
restart)
       sh /usr/local/tomcat/bin/shutdown.sh
       sh /usr/local/tomcat/bin/startup.sh
       ;;
esac   
exit 0

далее сделаем этот скрипт запускаемым:
sudo chmod 755 /etc/init.d/tomcat

для проверки работы запустим tomcat:
sudo /etc/init.d/tomcat start

сервер должен запуститься на 80 порту. Для остановки используем следующую команду:
sudo /etc/init.d/tomcat stop

создадим ссылки на скрипт для автоматического запуска и останова:
sudo update-rc.d tomcat defaults

перезагружаем сервер:
sudo shutdown -r now

в конце надо не забыть создать пользователя tomcat с ролями admin-gui и manager-gui в conf\tomcat-users.xml:



четверг, 9 июня 2011 г.

Double checked locking

Шаблон проектирования "Блокировка с двойной проверкой" используется в многопоточном программировании. Это один из излюбленных вопросов на собеседованиях. Звучит он обычно как просьба написать синглетон, корректно работающий в многопоточном режиме.

Рассмотрим принцип паттерна на примере Синглетона.
// Не работает в Java 1.4 и более ранних версиях из-за семантики volatile
class Foo {
  private volatile Helper helper = null;  

  public Helper getHelper() {
    if (helper == null) {          //блок проверки, для ускорения производительности
      synchronized(this) {         //блок синхронизации
        if (helper == null)        //если обьект еще не создан, то создаем его
          helper = new Helper();
      }
    }
    return helper;
  }
}

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

Модификатор volatile появился начиная с версии Java 1.5. Он позволяет корректно обработать запись в переменную в многопоточном режиме.

среда, 11 мая 2011 г.

Typesafe Enum pattern или как обойтись без Enum-ов.

Часто нужда в использовании Enum возникает в случае, если необходимо передать в метод одно из значений, например "green", "red" или "blue". Первое что приходит в голову - это принимать String:
public void method(String param) {...}

Но в таком случае в качестве параметра может быть принята любая строка. В соответствии с принципом, что все потенциальные ошибки по возможности надо переносить на момент компиляции, такой вариант неприемлем. Тут и приходит на помощь Enum:

public enum TypesafeEnum {GREEN, RED, BLUE};

А можно ли обойтись без него? Конечно можно, ведь Enum появились только с java 1.5. Тут нам может помочь паттерн Typesafe Enum:
public class TypesafeEnum {

  private final String name;

  private TypesafeEnum(String name) {
    this.name = name;
  }

  public static final TypesafeEnum GREEN = new TypesafeEnum("green");
  public static final TypesafeEnum RED = new TypesafeEnum("red");
  public static final TypesafeEnum BLUE = new TypesafeEnum("blue");

  public String toString() {
    return name;
  }
}
Теперь можно обьявить наш метод таким образом:
public void method(TypesafeEnum param) {...}
соответственно его вызов:
someObject.method(TypesafeEnum.RED);


Подробнее о паттерне здесь

пятница, 15 апреля 2011 г.

Паттерн Entity-Attribute-Value (EAV)

Паттерн "Entity-Attribute-Value" может пригодиться при проектировании базы данных товаров. Рассмотрим пример на СУБД Oracle.

В простейшем случае структура базы данных будет выглядеть следующим образом:
-- Create table
create table entity
(
  entity_id number,
  name      varchar2(50)
);
-- Create/Recreate primary, unique and foreign key constraints 
alter table entity
  add constraint xpk_entity_id primary key (ENTITY_ID);
Таблица Entity хранит сами сущности - товары. В качестве полей указываем общие свойства сущностей, таких как Название товара
-- Create table
create table attribute
(
  attribute_id   number,
  attribute_name varchar2(50),
  attribute_type varchar2(10),
  decriptions    clob
);
-- Create/Recreate primary, unique and foreign key constraints 
alter table attribute
  add constraint xpk_attribute_id primary key (ATTRIBUTE_ID);
Таблица Attribute хранит различные свойства товаров - атрибуты. В качестве полей указываем название атрибута, тип.
-- Create table
create table value
(
  attribute_id   number,
  entity_id      number,
  string_value   varchar2(100),
  number_value   number
);
таблица value - для хранения значений атрибутов, а также для связи многие ко многим между товарами и их атрибутами.

Реализация разных типов данных может быть реализована различными способами. Например вместо одного поля value можно создать разные поля под разные типы данных: string_value, number_value и использовать нужное исходя из типа атрибута из таблицы attribute.

Более подробная информация по паттерну

суббота, 9 апреля 2011 г.

Simple ORM

Наверное многие начинающие java программисты задумывались над тем, как неудобно писать слой взаимодейстия с базой данных на чистом JDBC. Ctrl+c, Ctrl+v и изменение названия таблиц и параметров. Все это приводит к излишнему дублированию кода. Конечно можно сразу взять тот же Hibernate или любую другую реализацию JPA. Но для небольших и простых проектов, имхо это как "из пушки по воробьям". К тому же считаю что надо один раз написать ORM самому, чтобы понять основы его работы.

В этой статье рассмотрим создание своего простого ORM на примере работы с СУБД Oracle.

Создадим интерфейс Persistence и реализующий его класс PersistenceOraImpl - собственно сам персистенс Api для работы с БД.

Список методов в Persistence:

1. selectAll - выбирает все записи из таблицы;
2. select - выбирает записи по заданным параметрам;
3. selectRow - выбирает одну запись по заданным параметрам;
4. insert - вставляет запись;
5. update - обновляет запись;
6. delete - удаляет запись.

Сам интерфейс выглядит так:
public interface Persistence {

 public List selectAll(Class<?> clazz);

 public List select(Class<?> clazz, Map<String, Object> params);

 public Object selectRow(Class<?> clazz, Map<String, Object> params);

 public void insert(Object obj);

 public void update(Object obj);

 public void delete(Class<?> clazz, Map<String, Object> params);

 public Connection getConnection();

 public void setConnection(Connection conn);
}

вторник, 5 апреля 2011 г.

Сериализация обьекта

отправка обьекта:
Message message = new Message();
 ByteArrayOutputStream fos = new ByteArrayOutputStream();
 ObjectOutputStream oos = new ObjectOutputStream(fos);
 oos.writeObject(message);
 oos.flush();
 oos.close();

 byte[] messageBodyBytes = fos.toByteArray();
где Message - POJO обьект.

Далее обьект можно записать в файл или отправить в сообщении.

прием обьекта:
ByteArrayInputStream fis = new ByteArrayInputStream(messageBodyBytes);
 ObjectInputStream oin = new ObjectInputStream(fis);
 Message mess = (Message) oin.readObject();

среда, 30 марта 2011 г.

Настраиваем поддержку русского языка в Linux Ubuntu

Открываем шелл: ALT+F2.

Обновляем репозиторий:
sudo apt-get update
Качаем саппорт языка, заодно всякие медиа и эмулятор windows:
sudo apt-get install language-support-ru ubuntu-restricted-extras wine

При установке шрифтов windows выскакивает лицензионное соглашение. Соглашаемся с ним TAB+ENTER.

После установки, для настройки переключения раскладки на клавиатуре редактируем файл:
sudo nano /etc/default/console-setup
Для переключения по CTRL+SHIFT зменяем строки:
XKBLAYOUT="us,ru"
XKBVARIANT=",winkeys"
XKBOPTIONS="grp:ctrl_shift_toggle"
Для переключения по ALT+SHIFT, устанавливаем параметр
XKBOPTIONS="grp:alt_shift_toggle"
перезагружаемся.