Monday, May 4, 2015

Малоизвестные Spring аннотации - @Primary

Сегодня поговорим о мало кому известной аннотации @Primary. Возможно, вы о ней читали, но возьмусь предположить, как и я, наверняка, не использовали.

Для внедрения зависимостей в Spring IoC используется @Autowired, если контейнер "находит" бин с указанным типом, то производит "инъекцию" - все предельно просто. Теперь рассмотрим пример, когда есть контракт некого бина и несколько реализаций(в нашем случае две). Для того чтобы "подсказать" контейнеру, что именно инжектить, обычно, используется аннотация @Qualifier, но есть еще один способ:

public interface Shape {
    int angles();
}

@Primary
@Component
public class Triangle implements Shape {
    @Override
    int angles(){ return 3; }
}

@Component
public class Square implements Shape {
    @Override
    int angles(){ return 4; }
}

@Component
public class ShapeManager {
    
    @Autowired
    private Shape shape;
}

Как можно догодаться, в ShapeManager будет внедрен бин помеченный как @Primary. Если заглянуть в доку, то гласит она буквально следующее: маркер(или индикатор) того, что данному бину будет отданно предпочнение среди прочих. Если существует только один класс помеченный данной аннотацией, то он будет внедрен в качестве зависимости.

Wednesday, April 1, 2015

Clojure Tips

Not so far, I found interesting resource, which contains tips for different programming languages. Here is the one for the clojure:

Sunday, November 23, 2014

Emacs как REST клиент

Короткий пост. Узнал, что помимо прочего у emacs-а есть замечательный REST клиент. Проект хостится на github-е. Небольшое дэмо:

Friday, June 13, 2014

Разработка OpenGL ES приложений на Linux

Намедни понадобилось разобраться с OpenGL ES версии 2+. Т.к. приставка ES подразумевает, что данная реализация OpenGL встраиваемая, то сразу же возник вопрос о комфортном рабочем окружении. В идеале мне нужно было иметь возможность запускать программы на моем PC без использования доп. устройств, эмуляторов. После недолго гугления на горизонте появилось несколько возможных решений. Я последовал самому простому из них. Все описанное ниже было выполнено на Debian Wheezy.

Настройка

Для начала нам нужно установить необходимы библиотеки и заголовочные файлы:

sudo apt-get update
sudo apt-get install freeglut3 freeglut3-dev binutils-gold g++ cmake libglew-dev mesa-common-dev build-essential libglew1.5-dev libglm-dev

После проверяем, что OpenGL и GLX доступны в нашей системе:

glxinfo | grep OpenGL
OpenGL vendor string: Tungsten Graphics, Inc
OpenGL renderer string: Mesa DRI Intel(R) Ironlake Desktop x86/MMX/SSE2
OpenGL version string: 2.1 Mesa 8.0.5
OpenGL shading language version string: 1.20
OpenGL extensions

Первая программа

Создадим отдельную директорию, куда добавим файл main.c следующего содержания:

#include <GL/freeglut.h>
#include <GL/gl.h>

void render(){
  glClearColor(0.0, 0.0, 0.0, 0.0);
  glClear(GL_COLOR_BUFFER_BIT);
  glColor3f(1.0, 1.0, 1.0);
  glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
  
  glBegin(GL_POLYGON);
  glVertex2f(-0.5, -0.5);
  glVertex2f(-0.5, 0.5);
  glVertex2f(0.5, 0.5);
  glVertex2f(0.5, -0.5);
  glEnd();
  glFlush();
}

int main(int argc, char** argv){
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_SINGLE);
  glutInitWindowSize(500, 500);
  glutInitWindowPosition(100, 100);
  glutCreateWindow("OpenGL - demo");
  glutDisplayFunc(render);
  glutMainLoop();
  return 0;
}

Makefile:

CC=gcc
SOURCES=$(wildcard *.c) 
C_FLAGS=
LD_FLAGS=-lglut -lGL -lGLEW -lGLU
OBJECTS=$(SOURCES:.c=.o)
EXECUTABLE=main

all: $(SOURCES) $(EXECUTABLE) 

$(EXECUTABLE): $(OBJECTS)
 $(CC) $(OBJECTS) -o $@ $(LD_FLAGS) 

.c.o:
 $(CC) $(C_FLAGS) $< -o $@

clean:
 rm -rf *o main

Сборка и запуск программы:

make
gcc -c -o main.o main.c
gcc main.o -o main -lglut -lGL -lGLEW -lGLU
./main

Ресурсы

Wednesday, April 30, 2014

Об ini-файлах в emacs-е

Использование различных конфигураций

Возникла необходимость запуска редактора emacs с различными конфигурациями. Например, в сегодня я работаю с clojure, а завтра, скажем, с python. Соотв. для каждого из случае я бы предпочел загружать лишь требуемые библиотеки и модули. По соглашению GnuEmacs использует следующие пути для конфигурационных файлов(может быть использован один из): ~/.emacs, _emacs, ~/.emacs.d/init.el. Но если нужно указать файл явно, то можно использовать следующий набор ключей:

emacs -q -l ~/my-init-file.el

Загрузка ini-файла

Допустим, имеем style.el, keys.el и modes.el, которые расположени в ~/.emacs.d/elisp. Для того чтобы загрузить их во время запуска, добавляем следующие строки в ini-файл:

(add-to-list 'load-path "~/.emacs.d/elisp/")
(load-library "style")
(load-library "keys")
(load-library "modes") 

Sunday, February 16, 2014

Доступ к ресурсам Android приложения

Бывает так, что во время разработки, нужно заглянуть в приватные директории приложения. Как известно, доступ к ним закрыт, и при попытке, скажем, получить список файлов, имеем следующее:

adennis@foofive ~ $ adb shell
shell@android:/ $ ls -al
...
drwxrwx--x system   system            2012-09-24 23:38 data
...
shell@android:/ $ cd data/
shell@android:/data $ ls
opendir failed, Permission denied

Есть несколько решений данной проблемы.

root

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

run-as

В составе Android OS есть утилита run-as. По своей сути очень похожа на sudo - выполнение команд от имени приложения или говоря короче - делегирование прав:

adb shell
run-as com.your.application ls -l /data/data/com.your.application
run-as com.your.application rm /data/data/comp.your.application/databases/database.db
…
# or your can run it in a interractive mode 
run-as com.your.application
shell@android:/data/data/com.your.application$ ls -l
cache
databases
lib
…

Пара моментов которые нужно знать... Приложение должно быть собрано как debuggable и в нек. случаях нужно менять права на файлы/директории:

adb shell 'run-as com.your.application chmod 666 /data/data/com.your.application/databases/databases.db'

Из недостатков можно назвать лишь одно - нет возможности доступа к файлам приложений третьих лиц(установленных, например, с Play Market).

backup

Последний способ. Я его использовал до того, как познакомился с run-as. Android предоставляет возможность сделать копию приложения:

adb -s [device id] backup -f backup.dat -noapk com.your.application

В текущей директории будет создан файл backup.dat([device id] можно узнать командой 'adb devices'). Далее распаковываем *.dat файл:

dd if=backup.dat bs=1 skip=24 | openssl zlib -d | tar -xvf -

Приведенная команда у меня работает только под Linux, под Mac OS я получаю сообщение об ошибке, мол openssl собран без поддержки zlib. Немного пошаманив, нашел решение, которое не требует пересборки openssl:

dd if=backup.dat bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" | tar -xvf -

По сравнению с Linux вариантом, работет медленнее, но для меня не критично. После всех шагов, в текущей директории будет создана папка apps, содержащая все внутренности приложения.

До недавнего времени последний способ не имел недостатков. Т.е. была возможность получить доступ ко всем потрохам без каких-либо ограничений. Но начиная с версии Android 4.4 в AndroidMainifext.xml был добавлен флаг allowBackup:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.your.application">
...
    <application
...
        android:allowBackup="true"/>
...
</manifest>

Который гласит буквально следующее: если флаг установлен в значение false, то приложение никогда не будет иметь возможность сделать резервную копию или восстанновление из резервной копии, даже в случае резерного копирования всей системы(имеется ввиду средствами самой ОС). Поумолчанию флаг имеет значение true. Вот такие дела. Т.е. доспут к ресурсам своего приложения мы всегда будем иметь, а в остальном - как повезет.

Источники

Форматирование в Mac OS

Обычно, я использую Linux в качестве основной ОС, но с недавних пор в арсенале появился Mac. Сегоднешний пост о том как быстро отформатировать внешний флэш накопитель(SD карту или USB донгл) не прибегая к GUI-шным утилитам. По шагам… Запускаем терминал и выполняем команду:

diskutil list

В моем случае вывод:

/dev/disk1
#:          TYPE NAME                    SIZE       IDENTIFIER
0:          GUID_partition_scheme       *16.0 GB    disk1
1:          EFI                         209.7 MB    disk1s1
2:          Apple_HFS Example            15.7 GB    disk1s2

Допустим, хотим отформатировать disk1:

sudo diskutil eraseDisk FAT32 [NAME] MBRFormat /dev/disk1

Где [NAME] имя, которое будет отображаться в качестве имени накопителя.