m_shige1979のときどきITブログ

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

JavaEEのサンプルアプリをCentOSに入れてみる

公開前の予行演習

実際にどうするかはわからないけどNetBeansで作成だけというのも変なので
ちょっとwarファイルをあげてみる

環境

vagrantのCentOS6.7
Java8
glassfish4.1

Vagrantの設定ファイル

Vagrantfile
#-*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure(2) do |config|
 # Every Vagrant development environment requires a box. You can search for
 # boxes at https://atlas.hashicorp.com/search.
 config.vm.box = "centos67_01"

 # Create a private network, which allows host-only access to the machine
 # using a specific IP.
 config.vm.network "private_network", ip: "192.168.33.10"

 # Share an additional folder to the guest VM. The first argument is
 # the path on the host to the actual folder. The second argument is
 # the path on the guest to mount the folder. And the optional third
 # argument is a set of non-required options.
 config.vm.synced_folder "./", "/vagrant", \
       create: true, owner: 'vagrant', group: 'vagrant', \
       mount_options: ['dmode=777,fmode=777']

 # Provider-specific configuration so you can fine-tune various
 # backing providers for Vagrant. These expose provider-specific options.
 # Example for VirtualBox:
 #
 config.vm.provider "virtualbox" do |vb|
   # Customize the amount of memory on the VM:
   vb.memory = "1024"
 end

end

ツールインストール

Java8
wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u91-b14/jdk-8u91-linux-x64.rpm
sudo rpm -ivh jdk-8u91-linux-x64.rpm
Glassfish4.1
wget http://download.java.net/glassfish/4.1/release/glassfish-4.1.zip
unzip glassfish-4.1.zip
sudo mv glassfish4 /usr/local/.
apache
sudo yum install httpd httpd-devel -y
sudo service httpd start
sudo chkconfig httpd on

glassfish設定

glassfishlocalhost以外で使用する場合はちょっと制限がある

起動
sudo /usr/local/glassfish4/bin/asadmin start-domain
管理者パスワード変更
$ sudo /usr/local/glassfish4/bin/asadmin change-admin-password
Enter admin user name [default: admin]>
Enter the admin password>
Enter the new admin password>
Enter the new admin password again>
Command change-admin-password executed successfully.
$

※ユーザーは"admin"、パスワードは空文字になっているのでそれ以降のところにパスワードを設定する

ログインストアにパスワードを登録
$ sudo /usr/local/glassfish4/bin/asadmin login
Enter admin user name [Enter to accept default]> admin
Enter admin password>
Login information relevant to admin user name [admin] for host [localhost] and admin port [4848] stored at [/root/.gfclient/pass] successfully.
Make sure that this file remains protected. Information stored in this file will be used by administration commands to manage associated domain.
Command login executed successfully.
$

※管理者パスワードと同じものにする

SSLを有効化
$ sudo /usr/local/glassfish4/bin/asadmin enable-secure-admin
You must restart all running servers for the change in secure admin to take effect.
Command enable-secure-admin executed successfully.
$
glassfish再起動
$ sudo /usr/local/glassfish4/bin/asadmin stop-domain
Waiting for the domain to stop .
Command stop-domain executed successfully.
[vagrant@localhost ~]$ sudo /usr/local/glassfish4/bin/asadmin start-domain
Waiting for domain1 to start .....
Successfully started the domain : domain1
domain  Location: /usr/local/glassfish4/glassfish/domains/domain1
Log File: /usr/local/glassfish4/glassfish/domains/domain1/logs/server.log
Admin Port: 4848
Command start-domain executed successfully.
$

JavaDB制御

/usr/java/jdk1.8.0_91/jre/lib/security/java.policy
grant {
        // 追加
        permission java.net.SocketPermission "localhost:1527", "listen,resolve";
};

※最後の方に追加する

JavaDB起動
sudo /usr/local/glassfish4/bin/asadmin start-database
データベース作成
$ /usr/local/glassfish4/javadb/bin/ij
ijバージョン10.10
ij> connect 'jdbc:derby://localhost/MemoDB;create=true';
ij> create table memo(
>   id int not null generated always as identity ( start with 1, increment by 1),
>   memo varchar(512),
>   constraint pk_memo primary key(id)
> );
0行が挿入/更新/削除されました
ij> select * from memo;
ID         |MEMO
--------------------------------------------------------------------------------------------------------------------------------------------

0行が選択されました
ij> exit;
$

デプロイ

アプリケーションを指定してデプロイする

f:id:m_shige1979:20160601210839p:plain

warをアップロード

f:id:m_shige1979:20160601211011p:plain

パラメータ設定

f:id:m_shige1979:20160601211226p:plain

プロキシ設定

/etc/httpd/conf/httpd.conf
<IfModule mod_proxy.c>
ProxyRequests Off
<Proxy *>
    Order deny,allow
    Allow from all
</Proxy>
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
ProxyPassReverseCookieDomain 127.0.0.1:8080 192.168.33.10
ProxyPassReverseCookiePath / /
</IfModule>

※末尾に追加

再起動
sudo service httpd restart

確認

f:id:m_shige1979:20160601211901p:plain

所感

とりあえずこんな感じで対応する。
http://ほげほげ/の場合の画面をどうするか考えないといけない
なかなか設定サンプルがないのでいろいろ探して考えてみる

JavaEE7でJavaMailを試す

環境

NetBeans8.1
Glassfish4.1

問題点

Glassfish4.1.1ではなぜかglassfishのメールセッションの設定ができない

参考

www.youtube.com
※英語でも動画で作業をなぞるとできるもんです

画面設定

index.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form prependId="false">
            <h:commandButton value="送信" action="#{mailBean.send()}"></h:commandButton>
        </h:form>
    </h:body>
</html>
MailBean.java
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package bean;

import javax.annotation.Resource;
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

/**
 *
 */
@Named(value = "mailBean")
@RequestScoped
public class MailBean {

    @Resource(name="mail/gmail")
    private Session session;
    
    public void send(){
        Message msg = new MimeMessage(session);
        
        try{
            msg.setSubject("aaaaa");
            msg.setText("aaaaaaa");
            msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse("送信先のメールアドレス@gmail.com"));
            
            Transport.send(msg);
            
        } catch(MessagingException e){
            e.printStackTrace();
        }
    }
     
}

glashfish設定

f:id:m_shige1979:20160529220519p:plain
f:id:m_shige1979:20160529220529p:plain
f:id:m_shige1979:20160529220538p:plain

ここまで

所感

Javaの場合は最新の技術というより保守に向けてのやり方の方が安定しているので
あまり最新のことに凝った情報が見つけきれない感じがする。
あったと思ってもちょっとコアすぎでで???って状態があるので
自分がつまづいている部分が本来ありえない場所だからかな…

JavaEEでのサンプルとしてメモアプリを作成してみた

Javaでの開発は基本的にはほとんどない

ちょっとやってみた

開発環境

Mac
Java Version8
NetBeans8.1

参考情報

Javaエンジニア養成読本 [現場で役立つ最新知識、満載!] (Software Design plus)

Javaエンジニア養成読本 [現場で役立つ最新知識、満載!] (Software Design plus)

※mevenでのチュートリアルをやってみたけどエラー出まくったので作成方法は変えてある

できたもの

https://github.com/mshige1979/javaee_memoapp
※ちょっとこれじゃない感あるけど

デモ


プロジェクトを作成

f:id:m_shige1979:20160528162930p:plain
f:id:m_shige1979:20160528162938p:plain
f:id:m_shige1979:20160528162945p:plain
f:id:m_shige1979:20160528162951p:plain
f:id:m_shige1979:20160528163001p:plain
f:id:m_shige1979:20160528163008p:plain
f:id:m_shige1979:20160528163014p:plain

ソースコード

githubをみてください
基本的には同じ感じ

問題点・所感など

なんかビルドしても前のものが残ってたりして動かないことが多かった。
一度、glashfishを再起動したり、netbeansを再起動とかすると動くので結構解決しか感じがない。
flashオブジェクトのデータの生成やaction時の挙動などPHPと違ってなかなか手軽に実行できないのがネックかもしれない。

参考

わかりやすいJavaEEウェブシステム入門

わかりやすいJavaEEウェブシステム入門

Java EE 7徹底入門 標準Javaフレームワークによる高信頼性Webシステムの構築

Java EE 7徹底入門 標準Javaフレームワークによる高信頼性Webシステムの構築

HTMLやcssの情報はリソースファイルはどうするくらいでちょうど良かった気がする

デバッグでどうすんだろ?

途中で変数などを確認したいけどダンプの取り方がわからん。なんかログ出力のやつでもあるのかな…

MacにXamarin Studioをインストールしてみました

特に意味はない

C#とか使えないけどクロスプラットフォームはちょっと便利そうなので入れてみました

環境

Mac Book Air

ダウンロード

氏名やメールアドレスなどを設定すること

f:id:m_shige1979:20160501202726p:plain

ダウンロードできない場合はここのリンクで手動ダウンロードする

f:id:m_shige1979:20160501202727p:plain

インストール

インストーラーを起動してインストールを開始する

f:id:m_shige1979:20160501202728p:plain

f:id:m_shige1979:20160501202729p:plain

f:id:m_shige1979:20160501202730p:plain

f:id:m_shige1979:20160501202731p:plain

f:id:m_shige1979:20160501202732p:plain

f:id:m_shige1979:20160501202733p:plain

f:id:m_shige1979:20160501202734p:plain

起動してサンプルアプリを作成

「New Solution」をクリックする

f:id:m_shige1979:20160501202735p:plain

「Xamarin Forms App」を選択する

f:id:m_shige1979:20160501202736p:plain

アプリ名を設定して次へ

f:id:m_shige1979:20160501202737p:plain

アプリ名を確認して作成

f:id:m_shige1979:20160501202738p:plain

作成した初期はビルドはiOSになっている

f:id:m_shige1979:20160501202739p:plain

実行

f:id:m_shige1979:20160501202740p:plain
※画面がでかいので50%くらいに縮小

androidの場合はandroidのプロジェクトを選びデバイスを指定する

f:id:m_shige1979:20160501202741p:plain
※Genumotionも起動している場合は選ぶことができる

androidを起動確認

f:id:m_shige1979:20160501202742p:plain

おわり

所感

iOSandroidを同じソースで編集できるのは便利な感じ
xamarinの使い方もc#という言語もほとんど知らないので時間をとって少しずつ勉強していくことにしてみる

CentOS7.xをGUIを有効にしてインストール

ライセンスの設定が必要みたい

普段はvagrantとかでいれたり、最小パッケージとか入れるけどちょっとGUIを見てみたくなったので設定

環境

Mac Book Air
VMWare Fusion8

ダウンロード

CentOS-7-x86_64-DVD-1511.iso

インストール

インストール開始

f:id:m_shige1979:20160429110754p:plain

言語を設定

f:id:m_shige1979:20160429110803p:plain

設定画面を確認

f:id:m_shige1979:20160429110810p:plain

ソフトウェアの選択でGUIのアプリを設定する

f:id:m_shige1979:20160429110818p:plain

あとは適当にいれてからインストールする

f:id:m_shige1979:20160429110826p:plain

インストール中の画面

f:id:m_shige1979:20160429110833p:plain

ルートパスワード

f:id:m_shige1979:20160429110841p:plain

ユーザーの作成

f:id:m_shige1979:20160429110848p:plain

インストール完了後は再起動を行う

f:id:m_shige1979:20160429110856p:plain

ライセンス設定

ライセンス設定の確認が表示される

f:id:m_shige1979:20160429111406p:plain

質問に答えて同意するようにする

f:id:m_shige1979:20160429111438p:plain

初期設定

ログインする

f:id:m_shige1979:20160429111516p:plain

言語設定

f:id:m_shige1979:20160429111531p:plain

キーボード設定

f:id:m_shige1979:20160429111545p:plain

オンラインアカウントを設定(スキップ可能)

f:id:m_shige1979:20160429111602p:plain

設定完了

f:id:m_shige1979:20160429111610p:plain

マニュアル

f:id:m_shige1979:20160429111618p:plain


おわり

所感

最小構成の場合は10分〜15分くらいで終わるけどこの場合は30分くらいかかった…
visual studio codeとかlinuxでも動くらしいのでちょっと試してみたいかも…

cakephp3で複数データをインサート

データを登録する際

1件ずつ登録するか、一括で登録するか…

環境

CentOS7.x
php7.0.3
cakephp3.2.3

一括で登録

sample1

src/Shell/Sample1Shell.php

<?php
namespace App\Shell;

use Cake\Console\Shell;
use Cake\ORM\TableRegistry;

/**
 * Sample1 shell command.
 */
class Sample1Shell extends Shell
{

    /**
     * main() method.
     *
     * @return bool|int Success or error code.
     */
    public function main() 
    {

        // サンプルデータ準備
        $postList = [
            [
                "title" => "aaa1",
                "body" => "hogehoge1",
                "created" => date("Y-m-d H:i:s", strtotime("now")),
                "modified" => date("Y-m-d H:i:s", strtotime("now")),
            ],
            [
                "title" => "aaa2",
                "body" => "hogehoge2",
                "created" => date("Y-m-d H:i:s", strtotime("now")),
                "modified" => date("Y-m-d H:i:s", strtotime("now")),
            ],
            [
                "title" => "aaa3",
                "body" => "hogehoge3",
                "created" => date("Y-m-d H:i:s", strtotime("now")),
                "modified" => date("Y-m-d H:i:s", strtotime("now")),
            ],
        ];

        // テーブルオブジェクトを取得
        $posts = TableRegistry::get("Posts");
        // クエリーオブジェクトを取得
        $oQuery = $posts->query();

        // 配列単位にデータを設定
        foreach($postList as $post){
            // 1行ずつ設定
            $oQuery
                ->insert(['title', 'body', 'created', 'modified']) // キーを指定
                ->values($post);    // 明細を設定
        }

        // 実行
        $oQuery->execute();
    }
}

※モデルのsaveではないのでcreatedやmodifiedは任意で設定する必要があります。

SQL
INSERT INTO posts (
  title, body, created, modified
) VALUES 
 ('aaa1', 'hogehoge1', '2016-03-08 13:08:31', '2016-03-08 13:08:31'), 
  ('aaa2', 'hogehoge2', '2016-03-08 13:08:31', '2016-03-08 13:08:31'), 
  ('aaa3', 'hogehoge3', '2016-03-08 13:08:31', '2016-03-08 13:08:31')

一括で実行されています

一件ずつ登録

sample2

src/Shell/Sample2Shell.php

<?php
namespace App\Shell;

use Cake\Console\Shell;
use Cake\ORM\TableRegistry;

/**
 * Sample2 shell command.
 */
class Sample2Shell extends Shell
{

    /**
     * main() method.
     *
     * @return bool|int Success or error code.
     */
    public function main() 
    {
        // サンプルデータ準備
        $postList = [
            [
                "title" => "bbb1",
                "body" => "foofoo1",
            ],
            [
                "title" => "bbb2",
                "body" => "foofoo2",
            ],
            [
                "title" => "bbb3",
                "body" => "foofoo3",
            ],
        ];

        // テーブルオブジェクトを取得
        $posts = TableRegistry::get("Posts");

        // データを設定して複数のエンティティを取得
        $postsEntities = $posts->newEntities($postList);

        // データ数分保存する
        foreach($postsEntities as $entity){
            // 保存
            $posts->save($entity, ['atomic' => false]);
        }
    }
}

※createdなどは自動設定してくれる

SQL
INSERT INTO posts (title, body, created, modified) VALUES ('bbb1', 'foofoo1', '2016-03-08 13:23:24', '2016-03-08 13:23:24')
INSERT INTO posts (title, body, created, modified) VALUES ('bbb2', 'foofoo2', '2016-03-08 13:23:24', '2016-03-08 13:23:24')
INSERT INTO posts (title, body, created, modified) VALUES ('bbb3', 'foofoo3', '2016-03-08 13:23:24', '2016-03-08 13:23:24')

一件ずつ実行

所感

一括で登録できた方が楽なのでそちらを使う事になると思われる。変なデータになっていないかは別の方法でチェックして対応する
ビジネスロジックの場所に困りそうな状況になりつつあるけどまあ最初はコントローラーを困らせていこう(^ ^)

cakephp3でエラー画面

エラー画面を多少はカスタマイズしたい…

エラー内容自体はともかく、デフォルトのフォーマットはマズイし…

環境

CentOS7.x
php7.0.3
cakephp3.2.3

実装

エラー用コントローラーを作成

src/Controller/AppErrorController.php

<?php

namespace App\Controller;

use Cake\Controller\ErrorController;
use Cake\Event\Event;

/**
 * 独自のエラーコントローラー
 * Class AppErrorController
 * @package App\Controller
 */
class AppErrorController extends ErrorController
{
    /**
     * 描画前処理
     *
     * @param Event $event
     */
    public function beforeRender(Event $event)
    {
        // エラーの共通レイアウト名を指定
        // src/Template/Layout/error_layout.ctp
        $this->viewBuilder()->layout('error_layout');

        // エラーテンプレートパスを指定
        $this->viewBuilder()->templatePath('Error');
    }
}

※描画前にテンプレートパスやレイアウトを指定する

レンダラーを作成

src/Error/AppExceptionRenderer.php

<?php
namespace App\Error;

use Cake\Error\ExceptionRenderer;
use Exception;
use Cake\Log\Log;
use App\Controller\AppErrorController;

/**
 * 独自例外用レンダラー
 *
 * Class AppExceptionRenderer
 * @package App\Error
 */
class AppExceptionRenderer extends ExceptionRenderer
{

    /**
     * 独自のコントローラーを指定
     * @param Exception $exception
     * @return AppErrorController
     */
    protected function _getController()
    {
        // 独自のコントローラーを指定
        return new AppErrorController();
    }

    /**
     * 独自のテンプレート名を指定
     *
     * @param Exception $exception
     * @param string $method
     * @param int $code
     * @return string
     */
    protected function _template(Exception $exception, $method, $code)
    {
        // src/Template/Error/error_custom.ctp
        return $this->template = "error_custom";
    }
}

※テンプレートを指定

設定ファイルを編集

config/app.php

<?php
return [
    'Error' => [
        'errorLevel' => E_ALL & ~E_DEPRECATED,
        //'exceptionRenderer' => 'Cake\Error\ExceptionRenderer',
        'exceptionRenderer' => 'App\Error\AppExceptionRenderer',
        'skipLog' => [],
        'log' => true,
        'trace' => true,
    ],

※レンダラーを変更

エラー用レイアウトを作成

src/Template/Layout/error_layout.ctp

<!DOCTYPE html>
<html>
<head>
    <?= $this->Html->charset() ?>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>
        <?= $this->fetch('title') ?>
    </title>
    <?= $this->Html->meta('icon') ?>
    <?= $this->fetch('meta') ?>

    <link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/css/app.css">
    <?= $this->fetch('css') ?>

</head>
<body>
    <header id="header">
        <nav class="navbar navbar-default">
            <div class="container">
                <a class="navbar-brand" id="logo" href="/">
                    CakePHP3 Demo
                </a>
                <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                    <ul class="nav navbar-nav navbar-right hidden-sm">
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-12">
                <div style="">
                    <?= $this->Flash->render() ?>
                </div>
            </div>
        </div>
    </div>
    <div class="container-fluid">
        <?= $this->fetch('content') ?>
    </div>
    <footer>
    </footer>
    <script src="/js/jquery-2.2.1.min.js"></script>
    <script src="/bootstrap/js/bootstrap.min.js"></script>
    <?= $this->fetch('script') ?>
</body>
</html>

エラー用テンプレートを作成
<?php
use Cake\Core\Configure;
use Cake\Error\Debugger;
?>
<div class="row">
    <div class="col-md-12">
        <div style="width: 800px;margin: 0 auto;">
            <h2><?= __d('cake', 'An Internal Error Has Occurred') ?></h2>
            <p class="error">
                <strong><?= __d('cake', 'Error') ?>: </strong>
                <?= h($message) ?>
            </p>
            <?php if (!empty($error->queryString)) : ?>
                <p class="notice">
                    <strong>SQL Query: </strong>
                    <?= h($error->queryString) ?>
                </p>
            <?php endif; ?>
            <?php if (!empty($error->params)) : ?>
                    <strong>SQL Query Params: </strong>
                    <?= Debugger::dump($error->params) ?>
            <?php endif; ?>
            <?php if ($error instanceof Error) : ?>
                    <strong>Error in: </strong>
                    <?= sprintf('%s, line %s', str_replace(ROOT, 'ROOT', $error->getFile()), $error->getLine()) ?>
            <?php endif; ?>
            <?php
                echo $this->element('auto_table_warning');

                if (extension_loaded('xdebug')):
                    xdebug_print_function_stack();
                endif;

                $this->end();
            ?>

        </div>
    </div>
</div>

画面

f:id:m_shige1979:20160308004400p:plain
スタックトレースはおいおい対応する

所感

エラー画面って難しいと思います。よくわからないのでログ吐きまくって調べてしまった。
まだおかしい部分があるのですか今回はこれでなんとかする。