Технология Java

👁 67 просмотров

Большая статья про технологии Java, которая будет досконально подробно описывать каждую технологию, со вставками из Wikipedia и других ресурсов. Статья не будет содержать текст автора, а будет ограничиваться техническими терминами и схемами, которые будут приведены под разным углом для лучшего понимания и будет дополняться по мере возможности.

Общая иерархия платформ

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

Общие платформы

Java

Java — сильно типизированный объектно-ориентированный язык программирования, разработанный компанией Sun Microsystems (в последующем приобретённой компанией Oracle). Приложения Java обычно транслируются в специальный байт-код, поэтому они могут работать на любой компьютерной архитектуре, с помощью виртуальной Java-машины. Дата официального выпуска — 23 мая 1995 года.

JDK

JDK(Java Development Kit) — бесплатно распространяемый компанией Oracle Corporation (ранее Sun Microsystems) комплект разработчика приложений на языке Java, включающий в себя компилятор Java (javac), стандартные библиотеки классов Java, примеры, документацию, различные утилиты и исполнительную систему Java (JRE). В состав JDK не входит интегрированная среда разработки на Java, поэтому разработчик, использующий только JDK, вынужден использовать внешний текстовый редактор и компилировать свои программы, используя утилиты командной строки.

JRE

JRE(Java Runtime Environment) — среда выполнения для программ на Java, минимальная реализация виртуальной машины, необходимая для исполнения Java-приложений, без компилятора и других средств разработки. Состоит из виртуальной машины — Java Virtual Machine — и библиотеки Java-классов. JRE распространяется свободно и для большинства платформ может быть загружена с сайта Oracle.Средства разработки вместе с JRE входят в JDK.

JVM

JVM(Java Virtual Machine) — виртуальная машина Java — основная часть исполняющей системы Java, так называемой Java Runtime Environment (JRE). Виртуальная машина Java исполняет байт-код Java, предварительно созданный из исходного текста Java-программы компилятором Java (javac). JVM может также использоваться для выполнения программ, написанных на других языках программирования. Например, исходный код на языке Ada может быть откомпилирован в байт-код Java, который затем может выполниться с помощью JVM. JVM является ключевым компонентом платформы Java. Так как виртуальные машины Java доступны для многих аппаратных и программных платформ, Java может рассматриваться и как связующее программное обеспечение, и как самостоятельная платформа. Использование одного байт-кода для многих платформ позволяет описать Java как «скомпилировано однажды, запускается везде» (compile once, run anywhere).Виртуальные машины Java обычно содержат Интерпретатор байт-кода, однако, для повышения производительности во многих машинах также применяется JIT-компиляция часто исполняемых фрагментов байт-кода в машинный код.

KVM

KVM — (Kylobyte Virtual Machine) — это виртуальная машина Java разработанная фирмой Sun Microsystems и соответствующая спецификации JVM. KVM была написана с нуля на языке программирования C. Данная виртуальная машина была разработана специально для небольших устройств имеющих ограниченный объём оперативной памяти. Поддерживается ограниченный набор возможностей обычной JVM. Например, KVM может не поддерживать операции с плавающей точкой и финализацию объектов. Стандарт CLDC определяет использование KVM. Буква ‘K’ в начале названия KVM указывает на то, что данная JVM работает с килобайтами памяти, а не с мегабайтами.

Java Card RE

Java Card RE — Java Card Runtime Environment, среда ыполнения апплетов, которые написаны для программного интерфейся Java Card. RE включает в себя реализацию виртуальной машины Java Card, классов API Java Card и служб поддержки времени выполнения, таких как выбор и отмена выбора апплетов.

Java Card VM

Java Card Virtual Machine — Предоставляет набор инструкций виртуальной машины Java-карты (VM), поддерживаемого подмножеством языка Java и форматов файлов, используемых для установки апплетов и библиотек в устройства с поддержкой технологии Java Card.

Термины из раздела

Транслятор — программа или техническое средство, выполняющее трансляцию программы;

Трансляция программы — преобразование программы, представленной на одном из языков программирования, в объектный файл. Транслятор обычно выполняет также диагностику ошибок, формирует словари идентификаторов, выдаёт для печати текст программы и т. д.;

Объектный файл  — файл с промежуточным представлением отдельного модуля программы, полученный в результате обработки исходного кода компилятором. Объектный файл содержит в себе особым образом подготовленный код (часто называемый двоичным или бинарным), который может быть объединён с другими объектными файлами при помощи редактора связей (компоновщика) для получения готового исполнимого модуля, либо библиотеки;

Компоновщик (также редактор связей, от англ. link editor, linker) — инструментальная программа, которая производит компоновку («линковку»): принимает на вход один или несколько объектных модулей и собирает по ним исполнимый модуль;

Интерпретатор — программа (разновидность транслятора), выполняющая интерпретацию программы;

Интерпретация — пооператорный (покомандный, построчный) анализ, обработка и тут же выполнение исходной программы или запроса (в отличие от компиляции, при которой программа транслируется без её выполнения);

Компилятор — программа или техническое средство, выполняющее компиляцию;

Компиляция — трансляция программы, составленной на исходном языке высокого уровня, в эквивалентную программу на низкоуровневом языке, близком машинному коду (абсолютный код, объектный файл, иногда на язык ассемблера), выполняемая компилятором;

 

Программные интерфейсы(API)

Java EE

Java EE — (Java Platform, Enterprise Edition, до версии 5.0 — Java 2 Enterprise Edition или J2EE) — набор спецификаций и соответствующей документации для языка Java, описывающей архитектуру серверной платформы для задач средних и крупных предприятий.

Спецификации детализированы настолько, чтобы обеспечить переносимость программ с одной реализации платформы на другую. Основная цель спецификаций — обеспечить масштабируемость приложений и целостность данных во время работы системы. JEE во многом ориентирована на использование её через веб как в интернете, так и в локальных сетях. Вся спецификация создаётся и утверждается через JCP (Java Community Process) в рамках инициативы Sun Microsystems Inc.

Java SE

Java SE — (Java Platform, Standard Edition, ранее Java 2 Standard Edition или J2SE) — стандартная версия платформы Java 2, предназначенная для создания и исполнения апплетов и приложений, рассчитанных на индивидуальное пользование или на использование в масштабах малого предприятия. Не включает в себя многие возможности, предоставляемые более мощной и расширенной платформой Java 2 Enterprise Edition (J2EE), рассчитанной на создание коммерческих приложений масштаба крупных и средних предприятий.

Java SE Embedded

Java SE Embedded — (Oracle Java Standard Edition Embedded) позволяет пользователям разрабатывать высокофункциональные, надежные и портативные приложения для самых современных встроенных систем. Гибкость платформы Java позволяет пользователям разрабатывать безопасные, инновационные продукты, одновременно повышая экономию средств и ускоряя время выхода на рынок. Oracle Java SE Embedded представляет собой платформу разработки для встроенных устройств, которая обеспечивает лучшую в отрасли надежность, производительность, пропускную способность, безопасность и кросс-платформенную поддержку. Java SE Embedded выполняет такую же роль, что и Java ME Embeded в иерархии, но предназначен для более производительных встраиваемых систем.

Java ME

Java ME — (Java Platform, Micro Edition, ранее — Java 2 Micro Edition, J2ME) — подмножество платформы Java для устройств, ограниченных в ресурсах, например: сотовых телефонов, карманных персональных компьютеров, ресиверов цифрового телевидения, проигрывателей дисков Blu-ray.

Java ME Embedded

Java ME Embedded — это полноценный Java runtime, оптимизированный для устройств с ARM архитектурой и систем с ограниченными аппаратными возможностями. Java ME показывает себя во всей красе на платформах со слабыми вычислительными мощностями и небольшими ресурсами оперативной памяти, которые работают с сетевыми сервисами. Например, такими, как беспроводные модули, модули позиционирования, «умные» счетчики ресурсов, датчики мониторинга окружающей среды, вендинг-машины, телемедицина и, конечно, «умные» дома.

Java TV

Java TV — это технология на основе Java ME, которая обеспечивает эффективное, надежное и простое решение для разработки приложений Java, которые работают в телевизоре и приставках. Используя среду исполнения Java TV, разработчики могут легко создавать приложения, такие как электронные программные гиды (EPG), клиенты Video-on-Demand (VOD), игры и образовательные приложения, приложения для доступа к интернет-данным (например, погода, тикеры новостей, социальные сети), а на большинстве названий дисков Blu-ray — пользовательский интерфейс и бонусный контент.

Java Card

Java Card — версия Java-платформы для устройств с крайне ограниченными вычислительными ресурсами. По сравнению с другими версиями Java изменен байткод, требования к исполняющей платформе, состав стандартных библиотек.

Основное назначение продукта, как следует из названия, — применение в смарткартах. В связи с этим основной упор был сделан на поддержку стандартных криптоалгоритмов.

Java Card дает возможность безопасным образом устанавливать и исполнять небольшие Java-приложения (апплеты) на смарт-картах и других устройствах с весьма ограниченным объёмом памяти. Эта платформа позволяет поставщику программировать устройства и делать их адаптированными под конкретное применение. Java Card широко используется в SIM-картах и банкоматах.

 

Компоненты программного интерфейса Java SE

Java 2D

Java 2D API представляет собой набор классов для расширенной 2D-графики и изображений. Он охватывает линейное воспроизведение, текст и изображения в единой всеобъемлющей модели. API обеспечивает широкую поддержку компоновки изображений и изображений альфа-каналов, набор классов для обеспечения точного определения и преобразования цветового пространства и богатый набор ориентированных на дисплей операторов визуализации. Эти классы предоставляются в виде дополнений к пакетам java.awt и java.awt.image

Java 3D

Java 3D — это высокоуровневый API для 3D-графики, который реализован поверх низкоуровневого API, такого как OpenGL и DirectX. Java 3D основан на так называемом scene graph , который подчеркивает дизайн сцены и содержит геометрию, преобразования, освещение, материал, трансформирование, текстуры и т. д. Вместо рендеринга низкого уровня.

Java 3D API позволяет создавать трехмерные графические приложения и интернет-апплеты на базе Интернета. Он обеспечивает высокоуровневые конструкции для создания и обработки 3D-геометрии и построения структур, используемых для рендеринга этой геометрии. С помощью этого программного обеспечения вы можете эффективно определять и отображать очень большие виртуальные миры.

Как прикрепить домен или субдомен к проекту на Java EE / Tomcat, если у вас на сервере еще и Vesta CP со своим Apache/PHP

👁 36 просмотров

Допустим, есть такая ситуация, когда на сервере с одним IP — адресом вы хотите разместить параллельно и проекты PHP сервером Apache на порту 80/8080 и проекты Java EE, которые запущены на любом порту, к примеру на 8085, так как к порту 80/8080 уже не привяжешь. Сервер с PHP проектами управляются при помощи Vesta CP, поэтому весь арсенал управления доменами делаем и него. Ниже список операций для прикрепления.

  1. Первым делом прикрепляем наш домен, если он у нас другом ресурсе к нашему серверу через записи NS;
  2. Создаем новый WEB — хостинг с эти доменом через панель Vesta CP;
  3. После создания хостинга с этим доменом или поддоменом залезаем в корень хостинга и кидаем туда .htaccess с записями перенаправления на наш Java EE проект с его портом
RewriteEngine on
RewriteRule ^(.*)$ http://localhost:port/MyJavaProject/$1 [P]
#localhost - ip адрес нашего сервера
#port - порт, на котором запушен наш Tomcat
#MyJavaProject - контекст проекта

Деплой проекта war под Tomcat в среде Java EE. Статья 1001.

👁 65 просмотров

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

1.Есть готовый .war — проект, который надо развернуть на удаленном или локальном сервере

Что мы делаем:

  • берем ProjectName.war — проект и кидаем в папку webapps не меняя ни название и ни расширение после компиляции;
  • перезапускаем сервер Tomcat. В виндовс это можно сделать любым способом, а на сервере Linu[ выполняем команду:
sudo service tomcat9 restart
  • далее идем в строку нашего браузера запускаем в адресной сроке наш проект http://hostname:8085/ProjectName/ и ждем, в зависимости от веса вашего проекта через секунды или минуты задеплоится ваш проект и запустится;
  • закинутый исходник ProjectName.war в папке webapps не удалять, иначе проект раздеплоится, хотя и создается папка work/localhost/ProjectName/, но она пустая.

 

2. Есть готовый war — проект, нужно его задеплоить на сервер Tomcat при помощи менеджера проектов Tomcat

Что мы делаем:

  • Первым первым делом настраиваем сервер, чтобы иметь права на управление скриптами и проектами, для этого идем в папку /conf и редактируем там файл tomcat-users.xml, там, где упоминается юзер, примерно так
 <role rolename="manager-gui"/>
 <role rolename="manager-script"/>
 <role rolename="manager-jmx"/>
 <role rolename="manager-status"/>
 <role rolename="admin-gui"/>
 <role rolename="admin-script"/>
 
 <user username="user" password="password" roles="manager-gui,manager-script,manager-jmx,manager-status,admin-gui,admin-script"/>
  • далее устаналиваем права на папку webapps, как 777, если не будет работать то и на папку work. Потому что, есть случай, когда менеджер не может задеплоить ваш проект по причине нехватки прав на запись в эти папки, учитывая то, что он загружает в эти папки ваш проект и в случае ошибки может выдать вот такой текст
    <em>FAIL - Deploy Upload Failed, Exception: [java.io.FileNotFoundException: </em>
  • идем по адресу http://hostname:8085/manager/, страница запросит данные юзера, которые мы выше прописали в файле tomcat-users.xml в виде логина: user и пароля: password. После авторизации находим кнопку загрузки на сервер и загружаем наш проект ProjectName.war и запускаем по адресу  http://hostname:8085/ProjectName/

 

Установка сервера Tomcat 8/9 на Ubuntu 16

👁 58 просмотров

В данной теме рассмотрим установку Apache Tomcat 8/9 на ОС Ubuntu 16.

Обновление пакетов Ubuntu

Первым делом нам нужно обновить все пакеты Linux/Ubuntu командой в терминале

apt-get update && apt-get upgrade

Установка JDK

Вторым делом, конечно же, нам нужна среда выполнения Java, на котором, собственно, и написан данный сервер. Для установки JDK набираем команду

apt-get install default-jdk

Для проверки удачной установки выполнил команду вывода установленной версии JDK

java -version

Это должно вывести что-то на подобие

openjdk version "1.8.0_111"
OpenJDK Runtime Environment (build 1.8.0_111-8u111-b14-2ubuntu0.16.04.2-b14)
OpenJDK 64-Bit Server VM (build 25.111-b14, mixed mode)

Добавление нового пользователя для работы с сервером

Это не обязательно, но из-за соображения безопасности не рекомендуется работать с сервером из пользователя root и поэтому, добавим нового пользователя для этого в систему

useradd -r username --shell /bin/false

 

Скачка архива Tomcat 8/9 и установка

Для установки нам надо будет скачать архив с Tomcat 8 или Tomcat 9. В данном примере установим версию 9. Разницы в установке версий 8 и 9 нет. Для скачки нужно знать текущее зеркало загрузки, они могут меняться и на данный момент, официальным зеркалом была ссылка на странице загрузки

копируем эту ссылку в буфер, заходим в раздел /opt

cd /opt

и скачиваем в данный раздел архив с сервером

wget http://apache-mirror.rbc.ru/pub/apache/tomcat/tomcat-9/v9.0.0.M22/bin/apache-tomcat-9.0.0.M22.tar.gz

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

tar -zxf apache-tomcat-9.0.0.M22.tar.gz

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

ln -s apache-tomcat-9.0.0.M22 tomcat-latest
chown -hR username: tomcat-latest apache-tomcat-9.0.0.M22

Создание сервиса для работы с сервером

Для работы с сервером в виде сервиса из командной строки необходимо создать специальный файл с именем сервиса и расширением *.service в папке /etc/systemd/system/, в данном случае именуем данный сервис как tomcat.service, в котором пропишем список операций для запуска, рестарта и остановки сервера Tomcat

[Unit]
Description=Tomcat9
After=network.target

[Service]
Type=forking
User=username
Group=usergroup

Environment=CATALINA_PID=/opt/tomcat-latest/tomcat.pid
Environment=JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-amd64
Environment=CATALINA_HOME=/opt/tomcat-latest
Environment=CATALINA_BASE=/opt/tomcat-latest
Environment="CATALINA_OPTS=-Xms512m -Xmx512m"
Environment="JAVA_OPTS=-Dfile.encoding=UTF-8 -Dnet.sf.ehcache.skipUpdateCheck=true -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:+UseParNewGC"

ExecStart=/opt/tomcat-latest/bin/startup.sh
ExecStop=/opt/tomcat-latest/bin/shutdown.sh

[Install]
WantedBy=multi-user.target

Сохраняем данный файл и запускаем сервер

systemctl daemon-reload
systemctl start tomcat
systemctl enable tomcat

 

Настройка сервера

Это базовый список операций для установки, далее нужно настроить установленный Tomcat, чтобы он работал на сервере через терни безопасности.

Tomcat на локальном сервере и удаленном работает по дефолту по разному. На локальном не возникают проблемы с правами и безопасностью, а на удаленном можно встретиться со всем этим сюрпризом и можно на этом убить немало времени.

Нам нужно, сначала дать полные права под папку проектов на удаленном сервере

далее, создать пользователя в файле конфигурации Tomcat — conf/tomcat-users.xml в каждом разделе в папке META-INF отредактировать файл context.xml.

Проблема входа в разделы менеджера приложений Tomcat 8/9 связана с блокировкой текущего URL, по которому мы пытаемся открыть сайт. Данная проблема решается , в дополнении с прописью ролей в tomcat-users.xml

 <role rolename="manager-gui"/>
 <role rolename="manager-script"/>
 <role rolename="manager-jmx"/>
 <role rolename="manager-status"/>
 <role rolename="admin-gui"/>
 <role rolename="admin-script"/>
 <user username="username" password="password" roles="manager-gui,manager-script,manager-jmx,manager-status,admin-gui,admin-script"/>

Еще и редактированием, точнее, закоментированием тега Valve в файле context.xml в папке META-INF открываемого проекта

<?xml version="1.0" encoding="UTF-8"?>
...
<Context antiResourceLocking="false" privileged="true" >
...
<!--
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
-->
...
</Context>

Файл context.xml может находится в любом проекте и отвечает за доступ к проекту из удаленного URL.

Вывод сообщения 403 Access Denied на Tomcat 8/9 в разделе Manager App/Host Manager/Server Status

👁 131 просмотров

В данном посте режим проблемы доступа в разделы менеджера и вообще, любого проекта, который мы ходим настроить на УДАЛЕННОМ СЕРВЕРЕ.


Почему именно на удаленном сервере? Потому что, работа Tomcat на локальном сервере и удаленном работает по дефолту по разному. На локальном не возникают проблемы с правами и безопасностью, а на удаленном можно встретиться со всем этим сюрпризом и можно на этом убить немало времени.

Нам нужно, сначала дать полные права под папку проектов на удаленном сервере

далее, создать пользователя в файле конфигурации Tomcat — conf/tomcat-users.xml в каждом разделе в папке META-INF отредактировать файл context.xml.

Проблема входа в разделы менеджера приложений Tomcat 8/9 связана с блокировкой текущего URL, по которому мы пытаемся открыть сайт. Данная проблема решается , в дополнении с прописью ролей в tomcat-users.xml

 <role rolename="manager-gui"/>
 <role rolename="manager-script"/>
 <role rolename="manager-jmx"/>
 <role rolename="manager-status"/>
 <role rolename="admin-gui"/>
 <role rolename="admin-script"/>
 <user username="username" password="password" roles="manager-gui,manager-script,manager-jmx,manager-status,admin-gui,admin-script"/>

Еще и редактированием, точнее, закоментированием тега Valve в файле context.xml в папке META-INF открываемого проекта

<?xml version="1.0" encoding="UTF-8"?>
...
<Context antiResourceLocking="false" privileged="true" >
...
<!--
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
-->
...
</Context>

Файл context.xml может находится в любом проекте и отвечает за доступ к проекту из удаленного URL.

Основные понятия в разработке Java EE

👁 39 просмотров

SNAPSHOT


Вопрос. Что значит приставка «-snapshot» в релизе «x.x.x-snapshot»?

  • Ответ 1. SNAPSHOT это зафиксированное состояние в системе управления версиями. Делаются ежедневно(или еженедельно, как разработка двигается). SNAPSHOT-версии могут оказаться вовсе не рабочими
  • Ответ 2. SNAPSHOT иногда означает, что это почти окончательный вариант данной версии. Что-то наподобие release candidate. Если обычная версия это полностью законченный продукт, то версии SNAPSHOT могут получать обновления, т.к. предполагается, что продукт ещё находится в стадии разработки. Более подробно можно почитать на английском SO здесь.
  • Ответ 3. SNAPSHOT означает, что исходники будут дорабатываться в пределах данной версии. Условно говоря, если твоё приложение использует некую библиотеку, помеченную как SNAPSHOT, то её автор, найдя баг или просто внеся дополнительный функционал, а может и удалив что-то, может залить новый jar’ник библиотеки (артефакта), при этом не поменяв версию. Совесть автора будет чиста, а вот твоё приложение, заново потянув библиотеку из репозитория может уже не собраться.

METADATA/meta data


Вопрос. Что такое METADATA/Метаданные?

  • Ответ 1. Метаданные — это субканальная информация об используемых данных.
  • Ответ 2. Структурированные данные, представляющие собой характеристики описываемых сущностей для целей их идентификации, поиска, оценки, управления ими или набор допустимых структурированных описаний, которые доступны в явном виде и предназначение которых может помочь найти объект.
  • Ответ 3. Термин используется в контексте поиска объектов, сущностей, ресурсов.
  • Ответ 4. Данные из более общей формальной системы, заданную с описывающей свойства системы данных.
  • Ответ 5. Информация о содержащейся на веб-странице свойств информации (создателе и т. п.). Пример: Имя автора правки в тексте. Этот термин в широком смысле слова используется для любой информации о данных: именах таблиц, колонок в таблице в реляционных базах данных, номер версии в файле программы (то есть как информативная часть в бинарном файле) и т. п.

WEB-INF


Вопрос. Что хранится в папке WEB-INF в проекте Java EE?

  • Ответ 1. Папка WEB-INF была создана специально, что-бы разграничить файлы классов и библиотеки классов используемые приложением от остальных html, jpg и прочих файлов, к которых пользователь должен иметь прямой доступ по протоколу http.
  • Ответ 2. Наличие папки WEB-INF — это одно из требований при развертке проекта Java EE:
    • Контейнер сервлетов (например, Tomcat) — если вы используете Apache Tomcat, корневой каталог приложения должен быть помещен в папку webapp. Это может быть другим, если вы используете другой контейнер сервлетов или сервер приложений.
    • API-интерфейс Java Servlet — Java Servlet Java Servlet API заявляет, что ваш корневой каталог приложения должен иметь следующую структуру:
      ApplicationName
      |
      |--META-INF
      |--WEB-INF
            |_web.xml       <-- Here is the configuration file of your web app(where you define servlets, filters, listeners...)
            |_classes       <--Here goes all the classes of your webapp, following the package structure you defined. Only 
            |_lib           <--Here goes all the libraries (jars) your application need

       

    • Ваш домен приложения — теперь, когда вы выполнили требования к контейнеру Servlet (или серверу приложений) и требованиям API Java Servlet, вы можете организовать другие части вашего веб-сервера на основе того, что вам нужно:
      • вы можете поместить свои ресурсы (файлы JSP, текстовые файлы, файлы сценариев) в корневой каталог приложения. Но тогда люди могут обращаться к ним напрямую из своего браузера, вместо того, чтобы их запросы обрабатывались по некоторой логике, предоставленной вашим приложением. Таким образом, чтобы ваши ресурсы не были доступны напрямую, вы можете поместить их в каталог WEB-INF, содержимое которого доступно только для сервера;
      • если вы используете некоторые фреймворки, они часто используют файлы конфигурации. Большинство этих фреймворков (классы, директории, …).
  • Ответ 3. Вы должны помещать WEB-INF любые страницы или части страниц, которые вы не хотите публиковать. Обычно JSP или facelets находятся вне WEB-INF, но в этом случае они легко доступны для любого пользователя. Если у вас есть некоторые ограничения авторизации, для этого можно использоваться WEB-INF.
  • Ответ 4. WEB-INF/lib может содержать сторонние библиотеки, которые вы не хотите упаковывать на системный уровень (JAR могут быть доступны для всех приложений, запущенных на вашем сервере), но только для этого конкретного приложения.
  • Ответ 5. Что касается WEB-INF/classes — он существует в любом веб-приложении, потому что это папка, в которой размещены все скомпилированные источники (а не JARS, а скомпилированные .java-файлы, которые вы написали сами).
  • Ответ 6. Вообще говоря, многие файлы конфигурации также входят в WEB-INF.
  • Ответ 7. Размещение файлов в WEB-INF соблюдается по соображениям безопасности. Например, если несанкционированному лицу разрешен доступ к корневому JSP-файлу непосредственно из URL-адреса, он может перемещаться по всему приложению без какой-либо проверки подлинности и получать доступ ко всем защищенным данным.

META-INF


Вопрос. Что хранится в папке META-INF в проекте Java EE?

  • Ответ 1. Вообще говоря, вы не должны вводить ничего в META-INF самостоятельно.
  • Ответ 2. Следующие файлы / каталоги в каталоге META-INF распознаются и интерпретируются платформой Java 2 для настройки приложений, расширений, загрузчиков классов и служб:
    • MANIFEST.MF — файл манифеста, который используется для определения данных, связанных с расширением и пакетом.
    • INDEX.LIST — файл генерируется новой -iопцией «» инструмента jar, которая содержит информацию о местоположении для пакетов, определенных в приложении или расширении. Он является частью реализации JarIndex и используется загрузчиками классов для ускорения процесса загрузки классов.
    • x.SF — файл подписи для файла JAR. «X» обозначает имя базового файла.
    • x.DSA — Файл блока подписи, связанный с файлом подписи с тем же именем базового файла. Этот файл хранит цифровую подпись соответствующего файла подписи.
    • services/ — в этом каталоге хранятся все файлы конфигурации поставщика услуг.
  • Папка META-INF — это домашний файл MANIFEST.MF . Этот файл содержит метаданные о содержимом JAR. Например, есть запись под названием Main-Class, которая указывает имя класса Java со статическим main () для исполняемых JAR-файлов.

 

Add Fragment as content to Activity in Android

👁 58 просмотров

Today we try add Fragment layout in another Activity layout, that reduce  complexity develop user interface. For this example we need 3 layout: main.xml, fragment1.xml, fragment2.xml, and 3 classes: MainActivity.java, Fragment1.java, Fragment2.java

Code of xml layouts

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"    >
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:text="I m fragment ONE"
        android:gravity="center"
        android:background="#5eff6a"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:text="I m fragment ONE"
        android:gravity="center"
        android:background="#5eff6a"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</LinearLayout>

 

Code of Java — classes

package com.example.dynamicfragments;

import android.support.v7.app.ActionBarActivity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;

public class MainActivity extends ActionBarActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		FragmentManager fm = getFragmentManager();
		FragmentTransaction fragmentTransaction = fm.beginTransaction();

		// get the display mode
		int displaymode = getResources().getConfiguration().orientation;
		if (displaymode == 1) { // it portrait mode
			Fragment1 f1 = new Fragment1();
			fragmentTransaction.replace(android.R.id.content, f1);
		} else {// its landscape
			Fragment2 f2 = new Fragment2();
			fragmentTransaction.replace(android.R.id.content, f2);
		}
		fragmentTransaction.commit();

	}
}

 

package com.example.dynamicfragments;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Fragment1 extends Fragment {
	public View onCreateView(LayoutInflater inflater, ViewGroup vg,
			Bundle savedInstanceState) {
		return inflater.inflate(R.layout.fragment1, vg, false);
	}
}

 

package com.example.dynamicfragments;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Fragment2 extends Fragment {
	public View onCreateView(LayoutInflater inflater, ViewGroup vg,
			Bundle savedInstanceState) {
		return inflater.inflate(R.layout.fragment2, vg, false);
	}
}

 

Conclusion result for this example

Create sliding menu-panel for android in fragment-layout

👁 45 просмотров

Hi All! In this post i am want to show you how to create android sliding panel for menu or content. This menu by founded on TranslateAnimation class.

For this we need one layout file bellow

XML code for this layout is shown bellow

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/RelativeLayout1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <SurfaceView
        android:id="@+id/surfaceView1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

    <RelativeLayout
        android:id="@+id/rlContentSliding"
        android:layout_width="220dp"
        android:layout_height="fill_parent"
        android:background="#BBB"
        android:orientation="vertical" >

        <LinearLayout
            android:id="@+id/llFakeLayout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical" android:visibility="gone">
        </LinearLayout>

        <ListView
            android:id="@+id/listView1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >
        </ListView>
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/rlContentMain"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#AfA"
        android:orientation="vertical">

        <LinearLayout
            android:id="@+id/llButtonLine"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true" android:background="#fff" android:layout_margin="2dp"
            android:weightSum="1">

            <Button
                android:id="@+id/button"
                android:layout_width="50dp"
                android:layout_height="wrap_content"
                android:text="slide"
                android:layout_weight="0.11" />
        </LinearLayout>

    </RelativeLayout>

</RelativeLayout>

Now we have to attach our layout as a fragment to the main Activity, adding events to the button in the method OnCreateView

public class SlideExampleFragment extends Fragment {
    View V;
    private Button buttonSwitch;
    private View subLayout;
    private View topLayout;
    private ListView subViewListView;
    private String listViewDummyContent[]={"Menu Item 1","Menu Item 2","Menu Item 3","Menu Item 2"};
    private Display display;
    private View fakeLayout;
    private Animation.AnimationListener AL;

    // Values for after the animation
    private int oldLeft;
    private int oldTop;
    private int newleft;
    private int newTop;
    private int screenWidth;
    private int animToPostion;
    // TODO change the name of the animToPostion for a better explanation.

    private boolean menuOpen = false;
    
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment

        V = inflater.inflate(R.layout.slide_layout, container, false);

        buttonSwitch = (Button)V.findViewById(R.id.button);
        subLayout = (View) V.findViewById(R.id.rlContentSliding);
        topLayout = (View) V.findViewById(R.id.rlContentMain);
        subViewListView=(ListView)V.findViewById(R.id.listView1);
        fakeLayout = (View)V.findViewById(R.id.llFakeLayout);

        subViewListView.setAdapter(new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1 , listViewDummyContent));

        display =  getActivity().getWindowManager().getDefaultDisplay();
        screenWidth = display.getWidth();
        int calcAnimationPosition = (screenWidth /3);

        // Value where the onTop Layer has to animate
        // also the max width of the layout underneath
        // Set Layout params for subLayout according to calculation
        animToPostion = screenWidth - calcAnimationPosition;

        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(animToPostion, RelativeLayout.LayoutParams.FILL_PARENT);
        subLayout.setLayoutParams(params);

        topLayout.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                if(event.getAction() == MotionEvent.ACTION_DOWN) {
                    if (menuOpen == true) {
                        animSlideLeft();
                    }
                }

                return false;
            }
        });

        buttonSwitch.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                if(menuOpen == false){
                    animSlideRight();
                } else if (menuOpen == true) {
                    animSlideLeft();
                }
            }
        });

        AL = new Animation.AnimationListener() {

            @Override
            public void onAnimationStart(Animation animation) {
                buttonSwitch.setClickable(false);
                topLayout.setEnabled(false);
            }
            @Override
            public void onAnimationRepeat(Animation animation) {
                // TODO Auto-generated method stub

            }
            @Override
            public void onAnimationEnd(Animation animation) {
                if(menuOpen == true) {
                    Log.d("", "Open");
                    topLayout.layout(oldLeft, oldTop, oldLeft + topLayout.getMeasuredWidth(), oldTop + topLayout.getMeasuredHeight() );
                    menuOpen = false;
                    buttonSwitch.setClickable(true);
                    topLayout.setEnabled(true);
                } else if(menuOpen == false) {
                    Log.d("","FALSE");
                    topLayout.layout(newleft, newTop, newleft + topLayout.getMeasuredWidth(), newTop + topLayout.getMeasuredHeight() );
                    topLayout.setEnabled(true);
                    menuOpen = true;
                    buttonSwitch.setClickable(true);
                }
            }
        };

        return V;
    }

    public void animSlideRight(){

        fakeLayout.setVisibility(View.VISIBLE);
        newleft = topLayout.getLeft() + animToPostion;
        newTop = topLayout.getTop();
        TranslateAnimation slideRight = new TranslateAnimation(0,newleft,0,0);
        slideRight.setDuration(500);
        slideRight.setFillEnabled(true);
        slideRight.setAnimationListener(AL);
        topLayout.startAnimation(slideRight);
    }

    public void animSlideLeft() {

        fakeLayout.setVisibility(View.GONE);
        oldLeft = topLayout.getLeft() - animToPostion;
        oldTop = topLayout.getTop();
        TranslateAnimation slideLeft = new TranslateAnimation(newleft,oldLeft,0,0);
        slideLeft.setDuration(500);
        slideLeft.setFillEnabled(true);
        slideLeft.setAnimationListener(AL);
        topLayout.startAnimation(slideLeft);
    }
}

End result for this post show bellow

Установка и настройка почтового SMPT-сервера Apache James 3.0

👁 118 просмотров

Проект Apache James предоставляет богатый набор модулей и библиотек, написанные на Java, связанные с Интернет — почтой, которые позволяют строить продвинутые почтовые сервера на уровне предприятий.

Все могут участвовать в сообществе разработки данного проекта при помощи подписки или следить за новостями в официальном аккаунте в Twitter — @ApacheJames.

Можно, также, посетить раздел wiki (рассказано как и кто используют Apache James,…)

Также, как и другие  Apache -проекты, Apache James был спроектирован открытым и на основе сотрудничества.

Что будет в статье?

В статье будет рассказано о том, как установить и запустить почтовый SMPT — сервер Apache James на Windows. Разрешим некоторые ситуации с ошибками и запустим сервер на локальном хосте.

Скачивание и установка

Есть 2 основных версий James Apache  — версия 2.3.x и версия 3.0(на момент написания данной статьи имела бета-версию 4). Оба версии в корне отличаются в плане настройки и развертывания и, так как, в статье рассмотрим версию 3.0, то у него есть свои ньюансы и дополнительные библиотеки, которые нужно будут скачать и включить в проект под Windows.

Установка сервера заключается в обычном разархивировании проекта, скачанного по ссылке.

Настройка конфигурации

В голом виде запустить Apache James не удастся, пока не будет сделана конфигурация. Для этого открываем файл конфигурации, находящийся в папке Apache James 3.0\conf\wrapper.conf.
В данном файле меняем, пока, 2 строчки кода:

...
wrapper.java.command=C:/Program Files/Java/jdk1.8.0_92/bin/java
...
wrapper.java.classpath.2=../conf/lib*
...

В первой строке мы изменили путь к java, который у нас установлен, а во второй указываем папку библиотек Apache James, которую мы будем использовать.

Это предварительная настройка Apache James, в дополнение нужно в переменных средах добавить путь к JDK, с с созданием новой переменной JAVA_HOME, если у вас это не настроено.

Запуск Apache James, забегая вперед

Забегая вперед, расскажу про ошибку, которая, возможно, вылетит после первоначальной настройки Apache James. Данный этап настройки и конфигурации считается законченной, но, если мы, сейчас попытаемся запустить, то Apache James выведет ошибку в консоли «wrapper | The Apache James Server App service was launched, but failed to start.»:

apache-james-server-start-failed

А если попытаемся запустить в службах Windows, то выведет ошибку «Ошибка 1067. Процесс был неожиданно завершен» или «Error 1067. The process terminated unexpectedly»:

apache-james-server-start-failed-from-services

Для решения проблемы с запуском сделаем дополнительную настройку с установками зависимостей.

Установка зависимостей

Для решения вышеизложенных проблем нужно сделать следующие шаги:

  • Добавляем новую сущность в classpath Apache James в файле wrapper.conf
    wrapper.java.classpath.120=../conf/lib/jaxb-impl-2.1.jar
    и скачиваем данную библиотеку через ссылку jaxb-impl-2.1.jar, после скачивания кидаем эту библиотеку в директорию Apache James 3.0/conf/lib
  • Скачиваем библиотеку JAXB2_20100510.jar и после скачивания кидаем эту библиотеку, так же, в директорию Apache James 3.0/conf/lib

Запуск Apache James

Для запуска сервера James мы должны запустить консоль с правами администратора, перейти в папку C:\Servers\Java\Apache James 3.0\bin и набрать в консоли команду:

>run.bat

Далее нужно установить Apache James в виде службы Windows, ля этого запускаем команду:

>james install

apache-james-server-start-failed

После запуска мы увидим его в списке служб Windows и для старта сервера нужно дать команду запуска:

>james start

Аналогично, для остановки:

>james stop

Для перезапуска:

>james restart

Чтобы удалить из спуска служб Windows набираем команду:

>james remove

Все, на этом установка, настройка и запуска SMPT-сервера на локальном Windows закончена.

JMySQL — готовый CRUD Java — класс для работы с БД MySQL

👁 49 просмотров

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

Пример использования

//Поля данных для соединения с БД
        public String driver = "com.mysql.jdbc.Driver";
        public String server = "localhost:3306";
        public String db = "myDbName";
        public String user = "root";
        public String password = "123456";
//Создаем объект класса
public JMySQL db = new JMySQL();
//Соединяемся с БД
String status = db.connect(driver, server, db, user, password);
//Добавляем что-нибудь в БД
String result = db.insert("user",
                        new String[]{"login", "password", "email", "phone", "name", "surname"},
                        new String[]{"MyLogin", "123456", "mail@mail.com",  "8800 888 88 88", "David", "Amirkhanov"});

Описание методов

Текущая версия поддерживает 8 методов для работы с БД MySQL и дает возможность быстро и легко реализовать CRUD — структуру работы с БД из Java — кода.

  • String connect(…) — соединяет с БД;
  • String insert(…) — добавляет новые данные в таблице текущего подключения;
  • boolean update(…) — обновляет данные в таблице текущего подключения;
  • ResultSet read(…) — читает данные из таблицы текущего подключения;
  • boolean delete(…) — удаляет данные в таблице текущего подключения;
  • boolean contains(…) — проверяет значение на наличие по порядковому номеру столбца в таблице текущего подключения;
  • boolean contains(…)— проверяет значение на наличие по названию столбца в таблице текущего подключения;
  • void close(…) — закрывает соединение текущего подключения.

String connect(…)

Метод соединяет с БД и возвращает «ok» при удачном подключении или ошибку — при неудачном.

public String connect(String driver,String server,String db,String user, String password)
  • driver — драйвер БД. Для MySQL это значение равно «com.mysql.jdbc.Driver»;
  • server — адрес сервера;
  • user — пользователь БД;
  • password — пароль пользователя.

String insert(…)

Метод метод добавляет новые данные в текущую БД и возвращает «ok» при удачном добавлении или ошибку — при неудачном.

 public String insert(String tableName,String[] colNames,String[] colValues)
  • tableName — название таблицы;
  • colNames — массив названий колонок, в которую добавляются данные;
  • colValues — массив значений для соответствующих добавляемых колонок;

boolean update(…)

Метод обновляет данные в таблице в определенных колонках через SQL — запросы

 public boolean update(String tableName,String[] colNames,String[] colValues,String where)
  • tableName — название таблицы;
  • colNames — массив названий колонок, в которых обновляются данные;
  • colValues — массив значений для соответствующих обновляемых колонок;
  • where — SQL — запрос(без ключевого слова WHERE). Если запроса нет, то записываем пустую строку «»;

ResultSet read(…)

Метод читает данные из выбранной таблицы через SQL — запросы SELECT и WHERE. При удачном чтении возвращает массив данных в виде объекта ResultSet

public ResultSet read(String select,String tableName,String where)
  • select — SQL — запрос(значение пишется без SELECT и это значение, чаще всего, равно «*»);
  • tableName — название читаемой таблицы;
  • where — SQL — запрос(без ключевого слова WHERE). Если запроса нет, то записываем пустую строку «»;

boolean delete(…)

Удаляет данные из выбранной таблицы через SQL — запрос WHERE. Возвращает true при удачном выполнении и false — при неудачном

public boolean delete(String tableName, String where)

 

  • tableName — название таблицы
  • where— SQL — запрос(без ключевого слова WHERE). Если запроса нет, то записываем пустую строку «»;

boolean contains(…)

Проверяет значение на содержание его в определенной колонке таблицы через порядковый номер колонки. Возвращает true при нахождении и false — в противном случае

public boolean contains(String tableName,int colNumber, String eqValue)
  • tableName — название таблицы
  • colNumber— порядковый номер колонки;
  • eqValue— проверяемое значение;

boolean contains(…)

Проверяет значение на содержание его в определенной колонке таблицы через название колонки. Возвращает true при нахождении и false — в противном случае

public boolean contains(String tableName,int colName, String eqValue)
  • tableName — название таблицы
  • colNumber— название колонки;
  • eqValue— проверяемое значение;

void close(…)

Закрывает текущее соединение с БД. Ничего не возвращает и не принимает

public void close()