Thursday, July 22, 2010

Переменные среды в Linux

Установка некоторых переменных среды через консоль:

export JAVA_HOME=/path/to/java/jdk1.6.0_20
export PATH=$JAVA_HOME:$PATH

export M2_HOME=/path/to/java/maven
export M2=$M2_HOME/bin
export PATH=$M2:$PATH

export используется, если задается глобальная переменная. Если переменная локальная (т.е. только для данного процесса), то export не требуется.
Посмотреть значение переменной можно, например, так:

echo $PATH

Кстати, в отличие от Windows, в PATH элементы разделяются двоеточием, а не точкой с запятой.
Для того, чтобы переменные среды устанавливались при загрузке пользовательского профайла рекомендуется использовать ~/.pam_environment для того, чтобы добавить туда скрипт с заданием переменных. Общие рекомендации по установке persistent environment variables можно узнать, набрав в консоли man pam_env, либо здесь.

Как оказалось, ~/.pam_environment не является скриптовым файлом, а представляет собой лишь список переменных среды. К тому же, у меня не получилось переопределить PATH, используя упомянутый файл. Такое переопределение приводило к тому, что в машину вообще нельзя было залогиниться. Пришлось войти в консольном режиме и с помощью vim удалять строки в ~/.pam_environment, отвечающие за переопределение PATH.

В конце концов, я взял и добавил нужные строки для определения переменных среды в ~/.profile. Сработало.

Tuesday, July 13, 2010

Использование system properties в eclipse.ini

Понадобилась небольшая кастомизация eclipse.ini.
Потребовалось уметь создавать свои параметры из eclipse.ini и уметь читать их внутри eclipse. Первый поиск практически ничего не дал конкретного по eclipse, но нашелся другой, более общий варинт: использование системных свойств (system properties) java. Системное свойство можно определить через eclipse.ini в качестве аргумента java-машины, например:

...
-vmargs
-Dfile.encoding=UTF-8
-Dosgi.requiredJavaVersion=1.5
-DMyCustomProperty=aPropertyValue
-Xms256m
...

Теперь в коде можно получить значение свойства MyCustomProperty следующим образом:

String value = System.getProperty("MyCustomProperty");

Friday, July 9, 2010

Создание архивов с помощью VBS

Есть, на мой взгляд, красивый способ создания архивов с помощью VB-скрипта, который хочу выложить (автор скрипта не я, но в своих скриптах использую эту рутину оч. активно). Грубо, идея в том, чтобы создать файл пустого архива, а потом в него добавить средствами Shell файлики.


';===================================
';
'; Simple zipping routine:
';
'; source is folder path to be zipped (recursive zip)
'; dest is file path for output zip archive
';
'; the main idea comes from here:
';
'; http://www.codecomments.com/archive299-2006-2-295877.html
'; http://forum.script-coding.info/viewtopic.php?id=1020
';
';===================================
sub zip(source, dest)
'
' wait operation delay
'
const dt = 1000
Set fso = CreateObject("Scripting.FileSystemObject")
Set ShellApp = CreateObject("Shell.Application")

With fso.CreateTextFile(dest, True)
.Write Chr(80) & Chr(75) & Chr(5) & Chr(6) & String(18, Chr(0))
.Close
End With

ShellApp.NameSpace(dest).CopyHere source

WScript.Sleep dt
'
' waiting for acrhive creation
'
On Error Resume Next
Do
fso.OpenTextFile dest, 1, False
If Err.Number = 0 Then Exit Do
Err.Clear
WScript.Sleep dt
Loop
end sub

Wednesday, July 7, 2010

Некоторые скриптинговые рутины на VBS

Давно хотел выложить код на VBScript, который я использовал в скрипте для публикации проекта (под публикацией понималось выкладывание сборки в базу данных Lotus Notes и рассылка уведомлений по списку).

Работа с Lotus Notes в vbs:

sub run()
' получить сессию (COM-объект, соотв. важно,
' чтобы объект был зарегистрирован в Win-реестре)
Set nSession = CreateObject("Notes.NotesSession")
' получить базу
Set db = nSession.GetDatabase(STORAGE_DATABASE_SRV,STORAGE_DATABASE_PATH)
if not db is nothing then
' какая-то работа с базой
'...
'...
end if
' освобождеине COM-объекта
nSession = null
end sub



Сниппет с приаттачиванием файлов к документу:


const EMBED_ATTACHMENT = 1454
';================================================
';
'; Simple file attach routine
';
'; @param doc is Notes Document
'; @param itemName is RTF item name
'; @param path is path to the file to be attached
';================================================
sub attach(doc, itemName, path)
Set item = doc.getFirstItem(itemName)
if not item is nothing then
call doc.removeItem(itemName)
end if
Set rti = doc.CreateRichTextItem(ItemName)
Set object = rti.EmbedObject(EMBED_ATTACHMENT, "", path)
end sub

Запуск bin-файлов в Linux

Вот уже несколько дней живу под Ubuntu, после WinXP немного непривычно.
Скачал brand new гелиос, скачал jdk. Поставить jdk оказалось довольно просто, достаточно было только bin-файлу, в котором лежит установщик jdk присвоить атрибут x (exetuable). После WinXP для меня это было не очевидно.

Вот сниппет, где я разрешаю выполнение bin-файла, после чего я его запускаю на выполнение:

tim@epsilon:~/works/downloads$ sudo chmod +x jdk-6u20-linux-i586.bin
tim@epsilon:~/works/downloads$ ./jdk-6u20-linux-i586.bin


Было забавно запускать установку jdk через консоль, так как пришлось долго и нудно проматывать лицензионное соглашение, прочитав которое, я должен был вбить заветное yes в ответ на запрос "Do you agree to the above license terms? [yes or no]".

Tuesday, July 6, 2010

Настройка прокси для SVN клиента

При подключении через svn к внешнему репозиторию получил сообщение "could not connect to server (http://eclipse.gwf.svn.sourceforge)". Задал прокси в настройках клиента - все заработало.

Шаблон для задания параметров в win-реестре:


Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Tigris.org\Subversion\Servers\global]
"http-proxy-host"="abcproxy"
"http-proxy-password"="pwrd"
"http-proxy-port"="8080"
"http-proxy-username"="ABCCORP\\usr"


Существует еще ряд других способов настройки конфигурации svn-клиента, о которых
можно подробно почитать в документации, гл. 7:

Ben Collins-Sussman, Brian W. Fitzpatrick, C. Michael Pilato: Version Control with Subversion For Subversion 1.5, Chapter 7. Customizing Your Subversion Experience

Tuesday, June 29, 2010

Перегрузка equals в Java

На днях проходил собеседование в одной компании, на котором попался вопрос про перегрузку equals в Java. Оказалось, что я был не в курсе довольно элементарного, в то же время важного правила: перегрузил equals - перегрузи и hashCode. В переводе это сводится к след. набору простых правил:
  • R1. если класс перегружает equals, то класс должен перегрузить и hashCode
  • R2. когда оба equals и hashCode перегружены, они должны использовать одинаковый набор свойств класса
  • R3. если оба объекта equals, то и значения их hashCode должны совпадать
  • R4. если объект не изменяется то hashCode является первым кандидатом на ленивую инициализацию и кеширование
  • R5. существует известное заблуждение, что hashCode предоставляет уникальный идентификатор для каждого объекта. Это не так.

На stackoverflow.com нашел алгоритм для вычисления hashCode, который считается наиболее эффективным (могу только предположить, что он дает более или менее равномерный разброс значений). Почти для всех классов приемлимо разумной является реализация, предложенная в 8-м разделе книги Джоша Блоха "Эффективная Java". Также эта реализация хороша тем, что автор в своей книге приводит объяснение почему данный подход приемлем.

Сам подход описывается следующим набором правил:

A1. Создать переменную result целого типа и присвоить ей ненулевое значение.
A2. Для каждого поля, которое используется при сравнении в equals, хеш-код k вычисляется след.образом:
  • если поле f имеет тип boolean, то исп.: k = f? 0:1;
  • если поле f имеет тип byte, short или int: k=(int)f;
  • если поле f имеет тип long, то: k = (int)(f ^ (f >>> 32)), где >>> - беззнаковый сдвиг;
  • если поле f имеет тип float, то: k = Float.floatToIntBits(f);
  • если поле f имеет тип double, то: Double.floatToIntBits(f), а полученное значение уже обрабатывается как long;
  • если поле f - объект, используйте в качестве результата его k = hashCode(), если f == null, то k = 0;
  • если поле f - массив, то рассматривается каждый объект как отдельный элемент и хеш вычисляется рекурсивно с комбинированием значений так, как показано в A3.
A3. Вычислить результат с использованием полученного значения k:

result = 37 * result + k;

A4. Вернуть результат. Возвращенный результат будет иметь подходящее
распределение значений хеша в большинстве случаев.