Flutter(続き)

Google公式サイトを参考に、Flutterアプリ(ステップ2まで)を作成してみました。

Googleの本気度が伝わりました。

Hot Reloadは便利ですね。

iOSアプリも変更が即時反映していたのは驚きました。

今回の作品です。

f:id:unokun3:20191109142843p:plain

参考

Flutterに触ってみました

Googleが開発するスマートフォンアプリ環境であるflutterに触ってみました。 iOSAndroidの両方で動くアプリケーションを開発できます。

本家のチュートリアル(MacOS版)を実施しました。

macOS install - Flutter

作成したアプリが実機で動くところまでは確認できました。後はUI部品(Widget)がどれくらい使えるかですね。

flutter SDKインストール

二つの方法があります。どちらも大差ありません。

zipファイルをダウンロードして解凍する

flutter_macos_v1.9.1+hotfix.6-stable.zip

gitからcloneする

flutter/flutter: Flutter makes it easy and fast to build beautiful mobile apps.

# パスの設定
.zshrcに設定しておくと毎回設定する必要はない。
export PATH="$PATH:[flutterをダウンロード(clone)したディレクトリ]/flutter/bin"

# git版でもflutter dockerすると必要なモジュールをダウンロードしてくれる。
$ flutter doctor

flutter app作成

$ flutter create my_app

Platformごとのセットアップ

iOS setup

install Xcode

すでにcommand-line toolのインストール済みの場合にはなにも実行されません。

 $ sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
 $ sudo xcodebuild -runFirstLaunch

Set up the iOS simulator

シミュレータを起動します。

$ open -a Simulator

run a simple Flutter app

iOSのシミュレータを起動しておくと、iOSアプリが起動します。

$ cd my_app
$ flutter run
Downloading ios tools...                                            4.8s
Downloading ios-profile tools...                                    3.2s
Downloading ios-release tools...                                   12.9s

Launching lib/main.dart on iPhone 11 Pro Max in debug mode...
Running Xcode build...

 ├─Assembling Flutter resources...                          11.2s
 └─Compiling, linking and signing...                        17.9s
Xcode build done.                                           35.9s
Syncing files to device iPhone 11 Pro Max...
 9,682ms (!)

🔥  To hot reload changes while running, press "r". To hot restart (and rebuild
state), press "R".
An Observatory debugger and profiler on iPhone 11 Pro Max is available at:
http://127.0.0.1:57661/vBeZHgO6_xE=/
For a more detailed help message, press "h". To detach, press "d"; to quit,
press "q".

f:id:unokun3:20191104124756p:plain

Deploy to iOS devices

実機にdeployするためには、Xcodeからインストールする必要があります。Xcodeプロジェクトが作成されるのですね。

$ ls ios
Flutter                 Runner                  Runner.xcworkspace
Frameworks              Runner.xcodeproj        ServiceDefinitions.json

$ open Runner.xcodeproj

実機の場合には、signinする必要があります。

f:id:unokun3:20191104130107p:plain

モジュール管理にはcocoapodsを使っているようです。

$ sudo gem install cocoapods
Password:
Fetching: thread_safe-0.3.6.gem (100%)
Successfully installed thread_safe-0.3.6
Fetching: tzinfo-1.2.5.gem (100%)
...
Fetching: cocoapods-1.8.4.gem (100%)
Successfully installed cocoapods-1.8.4
30 gems installed

実機にインストールします。 f:id:unokun3:20191104131635j:plain

Android setup

Install Android Studio

割愛

Set up the iOS simulator(emulator)

Android StudioからAVD Managerを起動する。 f:id:unokun3:20191104125358p:plain

run a simple Flutter app

$ flutter run

Using hardware rendering with device Android SDK built for x86. If you get
graphics artifacts, consider enabling software rendering with
"--enable-software-rendering".
Launching lib/main.dart on Android SDK built for x86 in debug mode...
Running Gradle task 'assembleDebug'...
Running Gradle task 'assembleDebug'... Done                        79.4s
✓ Built build/app/outputs/apk/debug/app-debug.apk.
Installing build/app/outputs/apk/app.apk...                         3.5s
I/Choreographer( 5078): Skipped 56 frames!  The application may be doing too much work on its main thread.
D/EGL_emulation( 5078): eglMakeCurrent: 0xd8067180: ver 3 0 (tinfo 0xefade5e0)
I/OpenGLRenderer( 5078): Davey! duration=1339ms; Flags=1, IntendedVsync=231214310519, Vsync=232147643815, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=232154779768, AnimationStart=232154810458, PerformTraversalsStart=232154812593, DrawStart=232172042436, SyncQueued=232188163101, SyncStart=232221350860, IssueDrawCommandsStart=232221553060, SwapBuffers=232468630724, FrameCompleted=232587351657, DequeueBufferDuration=71181000, QueueBufferDuration=2190000,
Syncing files to device Android SDK built for x86...
D/EGL_emulation( 5078): eglMakeCurrent: 0xebd85420: ver 3 0 (tinfo 0xebd836d0)
Syncing files to device Android SDK built for x86...            13,622ms (!)
🔥  To hot reload changes while running, press "r". To hot restart (and rebuild
state), press "R".
An Observatory debugger and profiler on Android SDK built for x86 is available
at: http://127.0.0.1:58674/R0KmIpo2wI4=/
For a more detailed help message, press "h". To detach, press "d"; to quit,
press "q".

f:id:unokun3:20191104125336p:plain

実機にインストールします。

f:id:unokun3:20191104131823p:plain

その他

device一覧

Android

$ flutter devices
2 connected devices:

ANE LX2J                  • SCV7N18522006899 • android-arm64 • Android 9 (API
28)
Android SDK built for x86 • emulator-5554    • android-x86   • Android 9 (API
28) (emulator)

iPhone

$ flutter devices
1 connected device:

宇野昌明のiPhone • a5f6160a18c068493881fcd58ecf93eb8b81438a • ios • iOS 13.1.3

emulators一覧

$ flutter emulators
2 available emulators:

Nexus_5X_API_28         • Nexus 5X API 28         • Google • android
apple_ios_simulator     • iOS Simulator           • Apple  • ios

JVMの仕組み

JVMに関するとても分かりやすい記事です。

お勧めです。

第1回 JVMはどのようにメモリ空間を利用するのか:Javaはどのように動くのか~図解でわかるJVMの仕組み|gihyo.jp … 技術評論社

第1回 問題の発生に備えてどんなことを知っておくべきか:Javaでなぜ問題が起きるのか 〜システムをきちんと運用するための基礎知識|gihyo.jp … 技術評論社

Centos7でgit 2.x系を使う

古いバージョンのgitを削除

$ sudo  yum remove git

最新版のgitが入っているレポジトリを取得

$ sudo yum -y install https://centos7.iuscommunity.org/ius-release.rpm

デフォルト無効にする

# sudo cat vi /etc/yum.repos.d/ius.repo

[ius]
name = IUS for Enterprise Linux 7 - $basearch
baseurl = https://repo.ius.io/7/$basearch/
enabled = 0      # 1→0に変更
repo_gpgcheck = 0
gpgcheck = 1

確認

iusパッケージが無効になっていればOK

$ sudo yum repolist all
...
ius-archive/x86_64                 IUS for Enterprise Linux 7 - Arc 無効
ius-archive-debuginfo/x86_64       IUS for Enterprise Linux 7 - Arc 無効
...

インストール

$sudo yum install git --enablerepo=ius --disablerepo=base,epel,extras,updates

エラーが発生したので以下を試しました。

$sudo yum --enablerepo=ius list git2u

存在していたのでインストール。

$ sudo yum install git2u --enablerepo=ius

centosやめてubuntuに変えようかと思う今日この頃...

参考

coreファイルを使ったgoのデバッグ

以下の記事を参考にcore dumpからgoプログラムのデバッグする方法をためしてみた。

Analyzing Core Dump Generated By Go Program - Speaker Deck

C言語の場合gdbを使うが、go言語の場合、dlvを使うようだ。

覚えておいて損はなさそう。ただし、macosではcoreファイルが作成されないようだ。残念。

$ ulimit -c unlimited
$ cat main.go
package main

func main() {
    var p *int
    p = nil
    *p = 1
}

$ export GOTRACEBACK=crash
$ go build main.go
$ ./main
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x44ebb2]

goroutine 1 [running]:
panic(0x45d560, 0x4b7ce0)
    /usr/local/go/src/runtime/panic.go:556 +0x2cb fp=0xc000032720 sp=0xc000032690 pc=0x421edb
runtime.panicmem()
    /usr/local/go/src/runtime/panic.go:82 +0x5e fp=0xc000032740 sp=0xc000032720 pc=0x420f1e
runtime.sigpanic()
    /usr/local/go/src/runtime/signal_unix.go:390 +0x182 fp=0xc000032790 sp=0xc000032740 pc=0x4342f2
main.main()
    /home/unokun/work/go/main.go:6 +0x2 fp=0xc000032798 sp=0xc000032790 pc=0x44ebb2
runtime.main()
    /usr/local/go/src/runtime/proc.go:201 +0x207 fp=0xc0000327e0 sp=0xc000032798 pc=0x423bc7
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc0000327e8 sp=0xc0000327e0 pc=0x448d21

goroutine 2 [force gc (idle)]:
runtime.gopark(0x470bd8, 0x4b9ae0, 0x1410, 0x1)
    /usr/local/go/src/runtime/proc.go:302 +0xeb fp=0xc000032f80 sp=0xc000032f60 pc=0x423fab
runtime.goparkunlock(0x4b9ae0, 0x1410, 0x1)
    /usr/local/go/src/runtime/proc.go:308 +0x53 fp=0xc000032fb0 sp=0xc000032f80 pc=0x424053
runtime.forcegchelper()
    /usr/local/go/src/runtime/proc.go:251 +0xb3 fp=0xc000032fe0 sp=0xc000032fb0 pc=0x423e23
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc000032fe8 sp=0xc000032fe0 pc=0x448d21
created by runtime.init.4
    /usr/local/go/src/runtime/proc.go:240 +0x35

goroutine 3 [GC sweep wait]:
runtime.gopark(0x470bd8, 0x4b9ba0, 0x41140c, 0x1)
    /usr/local/go/src/runtime/proc.go:302 +0xeb fp=0xc000033780 sp=0xc000033760 pc=0x423fab
runtime.goparkunlock(0x4b9ba0, 0x47140c, 0x1)
    /usr/local/go/src/runtime/proc.go:308 +0x53 fp=0xc0000337b0 sp=0xc000033780 pc=0x424053
runtime.bgsweep(0xc000052000)
    /usr/local/go/src/runtime/mgcsweep.go:52 +0x8f fp=0xc0000337d8 sp=0xc0000337b0 pc=0x418a9f
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc0000337e0 sp=0xc0000337d8 pc=0x448d21
created by runtime.gcenable
    /usr/local/go/src/runtime/mgc.go:216 +0x58
[1]    29625 abort (core dumped)  ./main

$ ls
core.29625  main  main.go

$ dlv core main core.29625
Type 'help' for list of commands.
(dlv) bt
 0  0x000000000044a624 in runtime.raise
    at /usr/local/go/src/runtime/sys_linux_amd64.s:146
 1  0x00000000004344ab in runtime.dieFromSignal
    at /usr/local/go/src/runtime/signal_unix.go:424
 2  0x0000000000434928 in runtime.sigfwdgo
    at /usr/local/go/src/runtime/signal_unix.go:629
 3  0x0000000000433d08 in runtime.sigtrampgo
    at /usr/local/go/src/runtime/signal_unix.go:289
 4  0x000000000044a913 in runtime.sigtramp
    at /usr/local/go/src/runtime/sys_linux_amd64.s:353
 5  0x000000000044aa00 in runtime.sigreturn
    at /usr/local/go/src/runtime/sys_linux_amd64.s:445
 6  0x000000000043466a in runtime.crash
    at /usr/local/go/src/runtime/signal_unix.go:518
 7  0x00000000004224d7 in runtime.fatalpanic
    at /usr/local/go/src/runtime/panic.go:708
 8  0x0000000000421edb in runtime.gopanic
    at /usr/local/go/src/runtime/panic.go:556
 9  0x0000000000420f1e in runtime.panicmem
    at /usr/local/go/src/runtime/panic.go:82
10  0x00000000004342f2 in runtime.sigpanic
    at /usr/local/go/src/runtime/signal_unix.go:390
11  0x000000000044ebb2 in main.main
    at ./main.go:6
12  0x0000000000423bc7 in runtime.main
    at /usr/local/go/src/runtime/proc.go:201
13  0x0000000000448d21 in runtime.goexit
    at /usr/local/go/src/runtime/asm_amd64.s:1333
(dlv) frame 11
> runtime.raise() /usr/local/go/src/runtime/sys_linux_amd64.s:146 (PC: 0x44a624)
Warning: debugging optimized function
Frame 11: ./main.go:6 (PC: 44ebb2)
     1: package main
     2:
     3: func main() {
     4:     var p *int
     5:     p = nil
=>   6:      *p = 1
     7: }
(dlv) locals
p = (unreadable empty OP stack)
(dlv) disass
TEXT main.main(SB) /home/unokun/work/go/main.go
    main.go:6   0x44ebb0    31c0        xor eax, eax
    main.go:6   0x44ebb2    48c70001000000  mov qword ptr [rax], 0x1
    main.go:7   0x44ebb9    c3      ret
(dlv) regs
...
     Rax = 0x0000000000000000
...
(dlv)

Spring Boot(Jar)ファイルをAzure App Serviceにデプロイしてみました

以下の記事を参考にSpring Boot(Jar)ファイルをAzure App Serviceにデプロイしてみました。

Maven と Azure を使用して Spring Boot JAR ファイルのアプリをクラウドにデプロイする | Microsoft Docs

ポイントは、Azure CLIでpomを書き換えるところです。

ここでデプロイ先、モジュール(Jar/War)を決めることができます。後はデプロイするだけです。

Azure CLI のインストールは以下を参照してください。 Azure CLI のインストール | Microsoft Docs

spring-bootのサンプルアプリを使うので簡単に試すことができました。

手順

$ git clone https://github.com/spring-guides/gs-spring-boot
$ cd gs-spring-boot/complete

# ビルド & 実行
$ ./mvnw clean package
$ ./mvnw spring-boot:run

# 動作確認します
$ curl http://localhost:8080

# pom のbuildセクションに追加します。
$ cat pom.xml
<plugin>
 <groupId>com.microsoft.azure</groupId>
 <artifactId>azure-webapp-maven-plugin</artifactId>
 <version>1.6.0</version>
</plugin>

$ ./mvnw azure-webapp:config
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------< org.springframework:gs-spring-boot >-----------------
[INFO] Building gs-spring-boot 0.1.0
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- azure-webapp-maven-plugin:1.6.0:config (default-cli) @ gs-spring-boot ---
[WARNING] The plugin may not work if you change the os of an existing webapp.
Define value for OS(Default: Linux):
1. linux [*]
2. windows
3. docker
Enter index to use:
Define value for javaVersion(Default: jre8):
1. jre8 [*]
2. java11
Enter index to use:
Define value for runtimeStack(Default: TOMCAT 8.5):
1. TOMCAT 9.0
2. jre8
3. TOMCAT 8.5 [*]
4. WILDFLY 14
Enter index to use: 2
Please confirm webapp properties
AppName : gs-spring-boot-1559091271202
ResourceGroup : gs-spring-boot-1559091271202-rg
Region : westeurope
PricingTier : Premium_P1V2
OS : Linux
RuntimeStack : JAVA 8-jre8
Deploy to slot : false
Confirm (Y/N)? : Y

# pomのpluginセクションに追加されていることを確認します。

# デプロイします
$ ./mvnw clean package
$ ./mvnw azure-webapp:deploy

Home - Microsoft Azureにデプロイされていることを確認しブラウザでアクセスしてみます。

以下の画面が表示されれば成功です。 f:id:unokun3:20190804153850p:plain

GraalVMを試してみました

遅まきながら、GraalVMのサイトのGetting Startを試してみました。

Getting started with GraalVM

試してみるようdockerイメージが用意されています。Docker Desktopをインストール済みであればこれを使うのが簡単です。

サイトには、Node、RubyPythonを使ったサンプルもありますがまずはJavaで試してみました。

手順

# docker image取得
$ docker pull oracle/graalvm-ce:19.1.1

# docker imageに接続
$ docker run -it oracle/graalvm-ce:19.1.1 bash
bash-4.2# 

# 気持ち的にrootにファイルは作成しにくい
bash-4.2# cd home

# "Hello Word!"を出力するjavaファイル作成
bash-4.2# vi HelloWorld.java

bash-4.2# cat HelloWorld.java
public class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, World!");
  }
}

bash-4.2# javac HelloWorld.java
bash-4.2# java HelloWorld
Hello, World!

# native-imageを作成
# デフォルトでは入っていないのでダウンロードする
bash-4.2# install native-image
bash-4.2# native-image HelloWorld
bash-4.2# ./helloWorld
Hello, World!

# バイナリをhexdumpする
# elfファイルになっている。
bash-4.2# hexdump -C helloworld | head
00000000  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 3e 00 01 00 00 00  00 10 40 00 00 00 00 00  |..>.......@.....|
00000020  40 00 00 00 00 00 00 00  d0 0c 23 00 00 00 00 00  |@.........#.....|
00000030  00 00 00 00 40 00 38 00  09 00 40 00 26 00 25 00  |....@.8...@.&.%.|
00000040  06 00 00 00 05 00 00 00  40 00 00 00 00 00 00 00  |........@.......|
00000050  40 00 40 00 00 00 00 00  40 00 40 00 00 00 00 00  |@.@.....@.@.....|
00000060  f8 01 00 00 00 00 00 00  f8 01 00 00 00 00 00 00  |................|
00000070  08 00 00 00 00 00 00 00  03 00 00 00 04 00 00 00  |................|
00000080  38 02 00 00 00 00 00 00  38 02 40 00 00 00 00 00  |8.......8.@.....|
00000090  38 02 40 00 00 00 00 00  1c 00 00 00 00 00 00 00  |8.@.............|

# ファイルサイズ
bash-4.2# ls -l
total 2256
-rwxr-xr-x 1 root root 2299472 Jul 21 01:23 helloworld
-rw-r--r-- 1 root root     427 Jul 21 01:20 HelloWorld.class
-rw-r--r-- 1 root root     116 Jul 21 01:20 HelloWorld.java

# 実行時間
bash-4.2# time ./helloworld
Hello, World!

real    0m0.002s
user    0m0.000s
sys 0m0.000s
bash-4.2# java HelloWorld
Hello, World!
bash-4.2# time java HelloWorld
Hello, World!

real    0m0.076s
user    0m0.060s
sys 0m0.000s

以下の記事はJavaフレームワークをnative-imageで起動した結果です。今後の動きから目が離せません。

きしだのHatena

あと、同じ著者が書いたこの記事も参考になります。 native-imageとJITは同程度だと思っていたのですが、JITの方がこんなに早いとは思いませんでした。

GraalVMはどれだけ遅いか - きしだのHatena