понедельник, 17 февраля 2020 г.

Базовый Spring-проект на gradle, работающий со встроенным томкатом.

основная статья https://spring.io/guides/gs/spring-boot/

Создаём в эклипсе новый проект, в мастере выбираем gradle-project. Обновляем build.gradle: 
plugins {
id 'org.springframework.boot' version '2.2.4.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}

group = 'ru.ayakovlev'
version = '0.2.0'
sourceCompatibility = '1.8'

dependencies {
    // This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'org.springframework.boot:spring-boot-starter-web'

    testImplementation 'junit:junit:4.12'
}

repositories {
mavenCentral()
}

jar {
manifest {
attributes('Implementation-Title': project.name,
'Implementation-Version': project.version)
}
}

В файле gradle-wrapper.properties прописываем версию градла 4.10.2 : 
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists


Создаём маленький контроллер, который будет возвращать не html, а данные:
package ru.ayakovlev.electionAnalysis2.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

@RequestMapping("/")
public String index() {
return "Greetings from Spring Boot !";
}
}

Создаём класс приложения:
package ru.ayakovlev.electionAnalysis2;

import java.util.Arrays;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

@Bean
public CommandLineRunner commanLineRunner(ApplicationContext ctx) {
return args -> {
System.out.println("Let's inspect the beans provided by Spring Boot: ");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.println(beanName);
}
};
}

}


Запуск приложения из командной строки линукса:
./gradlew bootRun
В git bash остановить это приложение, к сожалению, невозможно. Поэтому лучше его запускать из Far-а командой:
gradlew bootRun
Чтобы освободит порт 8080, который не освобождается после запуска в баше, 
В командной строке Windows выполняем команду, которая сообщит нам номер процесса, блокирующего наш порт:
netstat -ano | findstr 8080
Мы получим примерно такой вывод:
C:\WINDOWS\system32>netstat -ano | findstr 8080
  TCP    0.0.0.0:8080           0.0.0.0:0              LISTENING       13496
  TCP    [::]:8080              [::]:0                 LISTENING       13496
Самый правый столбец скажет нам номер процесса.
Его мы завершаем с помощью команды:
taskkill /F /pid <process_number>

После запуска приложения в окне должен высыпаться длинный список загруженных бинов.

Если обратиться к серверу по адресу в командной строке или в браузере, то мы увидим приветствие, забитое в коде:
$ curl localhost:8080
Greetings from Spring Boot!

среда, 10 января 2018 г.

Системная синхронизация потоков в java через wait/notify и через join()

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

Второй поток уходит в режим ожидания с помощью метода wait() объекта Фрукт, прежде чем вызвать этот метод он должен заполучить его монитор, поэтому этот метод обёрнут в блок 
synchronized(fruit){
fruit.wait();
}
Первый поток, вырастив фрукт и желая получить готовый стейк должен разбудить второй поток, и делает он это с помощью метода ntify() объекта Фрукт, который также должен быть обёрнут в синхронизованный блок:
synchronized(fruit){
fruit.notify();
}

Полный код примера:
package ru.andrewyakovlev.quizfultest;

public class ThreadsTest {

public static void main(String[] args) {
System.out.println("Начал работу первый поток по выращиванию фрукта");
Fruit fruit = new Fruit();
Thread t = new Thread(){
public void run(){
System.out.println("\t\t Второй поток в полной готовности к получению фрукта и приготовлению из него стейка.");
while(fruit.getMaturity() == "green"){
System.out.println("\t\t Второй поток: фрукт ещё зелёный => ждём...");
try {
synchronized(fruit){
fruit.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("\t\t Второй поток: получен зрелый фрукт, СТЕЙК ПРИГОТОВЛЕН!");
}
};
t.start();
int i = 1;
while(fruit.getMaturity() == "green"){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(Math.random() > 0.75){
System.out.println("Первый поток: на " + i + " день фрукт созрел.");
fruit.setMaturity("red");
synchronized(fruit){
fruit.notify();
}
}else{
System.out.println("Первый поток: " + i++ + " день дождливо.");
}
}
System.out.println("Первый поток закончил выращивание фрукта.");
}

}

class Fruit{
String maturity = "green";

public String getMaturity() {
return maturity;
}

public void setMaturity(String maturity) {
this.maturity = maturity;
}
}

Поскольку в данном примере второму потоку для начала работы нужно дождаться окончания работы первого потока, то в данном случае мы можем сделать синхронизацию с помощью метода join(): мы убираем все синхронизованные блоки, в начале работы программы определяем ссылку на главный поток:
Thread mainThread = Thread.currentThread();
и в начале работы второго потока присоединяем его к первому:
mainThread.join();
Что означает, что продолжение выполнения этого потока начнётся только после завершения главного. Вот полный код:
package ru.andrewyakovlev.quizfultest;

public class ThreadsJoinTest {

public static void main(String[] args) {
System.out.println("Начал работу первый поток по выращиванию фрукта");
Thread mainThread = Thread.currentThread();
Fruit fruit = new Fruit();
Thread t = new Thread(){
public void run(){
System.out.println("\t\t Второй поток в полной готовности к получению фрукта и приготовлению из него стейка.");
try {
mainThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("\t\t Второй поток: получен зрелый фрукт, СТЕЙК ПРИГОТОВЛЕН!");
}
};
t.start();
int i = 1;
while(fruit.getMaturity() == "green"){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(Math.random() > 0.75){
System.out.println("Первый поток: на " + i + " день фрукт созрел.");
fruit.setMaturity("red");
}else{
System.out.println("Первый поток: " + i++ + " день дождливо.");
}
}
System.out.println("Первый поток закончил выращивание фрукта.");
}

}

четверг, 25 мая 2017 г.

Вопросы по PHP

Проверить и преобразовать POST параметр к int

$f = (int)"10 Little Piggies"; // вернёт 10
$f = (int)"this is 10 Little Piggies"; // вернёт 0

Перевод строки:

echo "\r\n"; // важно, чтобы были именно кавычки, а не апострофы
echo PHP_EOL; // важно отсутствие кавычек или апострофов                                   ↑




пятница, 11 сентября 2015 г.

Как сконфигурировать BitBucket Git репозиторий в вашем Eclipse-окружении? Контроль версий Git с Eclipse (EGit)

перевод статьи.

Bitbucket - это распределённая система контроля версий (DVCS), место хранения кода, которая поддерживает Mercurial and GitС Mercurial и Git ваши данные являются распределёнными по определению, но вам по-прежнему нужно место, чтобы делать их доступными и иметь возможность отслеживать процесс разработки. Здесь-то и появляется Bitbucket.

Bitbucket предоставляет полнофункциональную среду для управления вашим проектом разработки, включая репозиторий кода, wiki (разумеется, поддерживаемый Mercurial and Git - вы можете клонировать его), мощный отслеживатель ошибок, и простое взаимодействие с остальными.

Bitbucket забирает всю боль шаринга кода и даёт вам возможность сфокусироваться на том, что вы умеете делать лучше всего - на коде. Bitbucket предоставляет и коммерческие планы и бесплатные аккаунты. Он предоставляет бесплатные аккаунты с неограниченным числом приватных репозиториев (которые могут иметь до 5 юзеров в случае бесплатных аккаунтов).


Здесь быстрые шаги, чтобы установить BitBucket-репозиторий в вашу Eclipse-среду.

Step-1

Зарегистрируйтесь в Bitbucket.

Step-2

Создайте Private/Public репозиторий.

Step-3

На обзорной странице Overview page https://bitbucket.org/dashboard/overview,  просмотрите информацию о репозитории.
Bitbucket Dashboard Overview page
Адрес ссылки даст вам Repository URL , который мы позднее используем, чтобы импортировать проект в Eclipse.

Step-4

Теперь давайте подготовим Eclipse к Git.
  • Открываем Eclipse
  • Кликаем на меню  Help 
  • Кликаем Install New Software
Eclipse Install New Software

Step-5

Устанавливаем eGit в Eclipse. Контроль версий Git с Eclipse (EGit) – Tutorial.  Как использовать bitBucket с EGit в Eclipse.
URL: http://download.eclipse.org/egit/updates
Eclipse - Add Repository

Step-6

Выберите Eclipse Git Team Provider иJGit в опциях и click next иfinish для установки.
Eclipse Install Git

Step-7

Теперь откройтеPerspectiveи выберите Git из списка.
Eclipse Git Prospective

Step-8

Кликните кнопку Clone Repository
Clone Git Repository to Eclipse and Add to View

Step-9

Введите ваш Bitbucket URL и пользовательскую информацию как указано в диаграмме ниже. КликнитеNext и Finish. Потребности менять какую-либо информация в следующих окнах нет.
Clone Repository Options Page in Eclipse

Step-10

Теперь вы должны увидеть ваш Bitbucket репозиторий в eclipse.
Checked Out Bitbucket repository in Eclipse

Step-11

Теперь вы можете захотеть импортировать проект, так что вы сможете работать над кодом.
  1. Click
    1. ‘Windows’ >
    2. ‘Open Perspective’ >
    3. ‘Resource’
  2. Click
    1. ‘File’ >
    2. ‘Import’ >
    3. ‘Git’ >
    4. ‘Projects from Git’ >
    5. ‘Existing local repository’ >
    6. ‘Select a Git Repository’ >
    7. ‘Import as General Project’ >
    8. ‘Next’ >
    9. ‘Finish’
  3. После этого код должен появиться в вашем окне Project Explorer’ как обычный проект.
  4. Сделайте изменения в своих файлах, какие сочтёте нужными.
  5. Посмотрите во view  ‘Git Staging’,чтобы увидеть изменённые файлы и кликните ‘Commit and Push
Git Staging View in Eclipse
Пожалуйста, дайте мне знать, если вы столкнётесь с какими либо проблемами при установке. Что теперь? Теперь установите SmartGit с вашим BitBucket-репозиторием, чтобы делать все виды commit, put, и т.п. GIT-операций.
Спасибо,
Автор оригинального текста App Shah

вторник, 24 сентября 2013 г.

git - как использовать

Основы работы с git описан на странице http://rogerdudler.github.io/git-guide/
  1. устанавливаем консольное приложение git в зависимости от отперационной системы 
  2. создаём новую директорию, входим в неё и выполняем в ней
    git init
    чтобы создать новый репозиторий git
  3. создаём рабочую копию локального репозитория, выполнив следующую команду:
    git clone https://github.com/user/project
    если клонировать проект не удаётся и выдаётся ошибка:
    fatal index-pack failed git clone
    можно попробовать выполнить команду:
    git config --global core.compression -1
    которая установит гитовский глобальный конфиг-файл в $HOME/.gitconfig,
    Источник здесь.
    Или можно попробовать выполнить команду:
    git config pack.windowMemory 10m
    git config pack.packSizeLimit 20m
    Источник здесь.
  4. Поток работ
    Наш локальный репозиторий состоит из трёх деревьев, поддерживаемых гитом. Первое - это наша рабочая директория, которая содержит актуальные файлы, второе - это Index, которая работает как Staging area, и наконец HEAD, которая указывает на последний коммит, который мы сделали.

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

    git clone https://github.com/user/project - создаёт локальный репозиторий.

    Рабочая директория - это папка, файлы из которой мы затем будем редактировать, и после чего добавляем их слепки в область подготовленных файлов и делаем коммит (т.е. берём подготовленные файлы из индекса и помещаем их в локальный репозиторий на постоянное хранение.)
  5. add & commit
    мы можем предложить изменения (добавить их к Index) используя:
    git add <filename>
    git add *
    Это первый шаг в базовом потоке работ гита. Чтобы по-настоящему закомитить эти изменения, используем:
    git commit -m "Commit message"
    Теперь файл закомичен в HEAD, но пока не в удалённый репозиторий.
  6. Проталкивание изменений
    Теперь наши изменения в HEAD нашей локальной рабочей копии. Чтобы послать эти изменения в наш удалённый репозиторий, выполним:
    git push origin master
    master можно заменить на некую ветку, куда мы хотим отправить изменения.
  7. Если при попытке сделать push на удалённый сервер мы получаем ошибку:
    Updates were rejected because the tip of your current branch is behind its remote counterpart. Integrate the remote changes (e.g. 'git pull ...') before pushing again.
    Значит один из наших партнёров до нас уже внёс изменения в удалённый репозиторий, и нам надо забрать эти изменения и сделать слияние с ними:
    git pull
    git merge origin/master
    в последней команде origin - это ссылка на удалённый репозиторий, которая инициализируется при выполнении команды git clone, а master - имя ветки, с которой надо провести слияние.

вторник, 14 мая 2013 г.

Простое EJB 3 приложение из командной строки

В этом посте рассказывается, как создать простое EJB 3 приложение, которое написано, развёрнуто и запущено из командной строки. Не будет ни дескриптора развёртывания, ни клиентских стабов, ни файла jndi.properties. Целевой сервер приложений - glassfish. Англоязычный источник статьи здесь.

1. Структура директории проекта:
1
2
3
4
5
6
7
8
C:\simple-ejb3> tree /A /F
+---classes
|   \---foo
\---src
    \---foo
           Client.java
           FooBean.java
           FooRemote.java


2. В пакете foo в папке src/foo создадим 3 java-файла:
1
2
3
4
5
6
7
package foo;
import javax.ejb.*;
@Remote
public interface FooRemote {
public String echo(String s);
}


1
2
3
4
5
6
7
8
9
10
package foo;
import javax.ejb.*;
@Stateless
public class FooBean implements FooRemote {
public String echo(String s) {
  return s;
}
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package foo;
import javax.ejb.*;
import javax.naming.*;
public class Client {
public static void main(String[] args) throws Exception {
  Context ic = new InitialContext();
  Object obj = ic.lookup(FooRemote.class.getName());
  System.out.println("lookup returned " + obj);
  FooRemote foo = (FooRemote) obj;
  String input = (args.length > 0) ? args[0] :
              "No application arg specified.";
  String s = foo.echo(input);
  System.out.println("foo.echo returned " + s);
}
}


3. Компилируем java-файлы. Желательно для удобства установить переменную окружения JAVAEE_HOME, но это не обязательно.

1
2
C:\simple-ejb3\classes> set JAVAEE_HOME=C:\Program Files\glassfish-3.1.2.2\glassfish
C:\simple-ejb3\classes> javac -d . -classpath %JAVAEE_HOME%\lib\javaee.jar;. ..\src\foo\*.java
Если javac не является внутренней или внешней командой, или в пути к библиотекам окажется символ пробела как в вышеприведённом случае, тогда можно использовать более явную команду с помещением пути с пробелами в кавычки:
%JAVA_HOME%\bin\javac -d . -classpath "C:\Program Files\glassfish-3.1.2.2\glassfish\lib\javaee.jar;." ..\src\foo\*.java

4. Стартуем сервер приложений:

1
C:\simple-ejb3\classes> "%JAVAEE_HOME%\bin\asadmin.bat" start-domain


5. Пакуем и автодеплоим ejb-jar. Мы можем совместить два шага в одном используя %JAVAEE_HOME%\domains\domain1\autodeploy в качестве директории назначения (destdir)
1
C:\simple-ejb3\classes> %JAVA_HOME%\bin\jar cvf "%JAVAEE_HOME%\domains\domain1\autodeploy\foo-ejb.jar" foo\FooBean.class foo\FooRemote.class

Убедиться в удачном деплоинге можно зайдя в директорию %JAVAEE_HOME%\domains\domain1\autodeploy, там должы появиться пара файлов foo-ejb.jar и foo-ejb.jar_deployed.

6. Запускаем standalone клиент и смотрим на вывод:
1
2
3
4
C:\simple-ejb3\classes> java -cp "%JAVAEE_HOME%\lib\javaee.jar;%JAVAEE_HOME%\lib\appserv-rt.jar;." foo.Client
lookup returned foo._FooRemote_Wrapper@e9738564
foo.echo returned No application arg specified.


7. Если тестовый проект на сервере нам не нужен, сделаем его андеплой:
1
del %JAVAEE_HOME%\domains\domain1\autodeploy\*.jar