Indify String Concatenation
I am very interested about this http://openjdk.java.net/jeps/280. And I had a session about this which is presented by @bitter_fox who is one of JDK comitter.
Due to my poor skill, I have no idea about below difference which is the result of java.
Anyway I have to learn more...
code
- Sample.java
public class Sample{ public static void main(String... args){ Sample sample = new Sample(); String a = "a"; String b = "b"; String ab = sample.m(a,b); } String m(String a, String b){ return a + "(" + b + ")"; } }
javap
- JDK8
- JDK9(Indify String Concatenation)
Try to use Jigsaw(No2)
I just wanted to use Jigsaw by myself. So I found this articlehttp://openjdk.java.net/projects/jigsaw/quick-start and had the session about Jigsaw which is presented by @skrb. The material is here
I like this slide and I think this is worth to read.
code
- src/org.astro/module-info.java
module org.astro { exports org.astro; }
- src/org.astro/org/astro/World.java
package org.astro; public class World{ public static String name() { return "world"; } }
- src/com.greetings/module-info.java
module com.greetings { requires org.astro; }
- src/com.greetings/com/greetins/Main.java
package com.greetings; import org.astro.World; public class Main { public static void main(String... args) { System.out.println(String.format("Greeting %s", World.name())); } }
compile
javac -p mods -d mods/org.astro src/org.astro/module-info.java src/org.astro/org/astro/World.java javac -p mods -d mods/com.greetings src/com.greetings/module-info.java src/com.greetings/com/greetins/Main.java
Execute
java -p mods -m com.greetings/com.greetings.Main
result
Directory
packaging
jar --create --file=mlib/org.astro@1.0.jar --module-version=1.0 -C mods/org.astro . jar --create --file=mlib/com.greetings.jar --main-class=com.greetings.Main -C mods/com.greetings .
Execute
java -p mlib -m com.greetings
result
new option of jar
try to use Jigsaw
The original code is herehttp://openjdk.java.net/projects/jigsaw/quick-start
I just wanted to use Jigsaw.
Directory
code
- Main.java
package com.greetings; public class Main { public static void main(String... args) { System.out.println("Greetings!"); } }
- module-info.java
module com.greetings { }
compile
javac -p mods -d mods/com.greetings src/com.greetings/module-info.java src/com.greetings/com/greetins/Main.java
Execute
java -p mods -m com.greetings/com.greetings.Main
result
how to cast long value to int
This is just memo about how to cast long value to int.
From JavaSE8 you can use Math.toIntExact to avoid overflows while you do not know.
Sample.java
public class Sample { public static void main(String... args) { Sample sample = new Sample(); sample.cast(); sample.intExact(); } void cast() { System.out.println("----- cast -----"); int i; long l = Long.MAX_VALUE; i = (int) l; System.out.println(String.format("i=%d", i)); System.out.println(String.format("l=%d", l)); } void intExact() { System.out.println("----- intExact -----"); int i; long l = Long.MAX_VALUE; i = Math.toIntExact(l); // <--- This method was added from JavaSE8 System.out.println(String.format("i=%d", i)); System.out.println(String.format("l=%d", l)); } }
The result
The following result shows the difference between cast and Math.toIntExact.
Creating Directory by NIO2
creating directory
- create dir1
- create dir2/dir3 with permission("rwxrwxr-x")
As you can see the below result, the permission is set only to the dir3.
This is obvious, since Files.setPosixFilePermissions apply only to the path(dir3).
Anyway it is possible to set permission depending on the OS.
I find out this function when reading Java SE7/8 速攻入門, author is @skrb, who is Java champion.
package com.test; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.PosixFilePermission; import java.nio.file.attribute.PosixFilePermissions; import java.util.Set; public class Test { public static void main(String[] args) throws Exception { Test test = new Test(); test.createDir("/Users/tomo/dir1"); test.createDir("/Users/tomo/dir2/dir3", "rwxrwxr-x"); } private void createDir(String dirPath) throws Exception { Path path = Paths.get(dirPath); Files.createDirectories(path); } private void createDir(String dirPath, String permission) throws Exception { Path path = Paths.get(dirPath); Files.createDirectories(path); Set<PosixFilePermission> permissionSet = PosixFilePermissions.fromString(permission); Files.setPosixFilePermissions(path, permissionSet); // *** set permission } }
Permission error
You can not set permission SUID, SGID and Sticky bit...
I just wanted to set it.
PosixFilePermissions.java
public static Set<PosixFilePermission> fromString(String perms) { if (perms.length() != 9) throw new IllegalArgumentException("Invalid mode"); Set<PosixFilePermission> result = EnumSet.noneOf(PosixFilePermission.class); if (isR(perms.charAt(0))) result.add(OWNER_READ); if (isW(perms.charAt(1))) result.add(OWNER_WRITE); if (isX(perms.charAt(2))) result.add(OWNER_EXECUTE); if (isR(perms.charAt(3))) result.add(GROUP_READ); if (isW(perms.charAt(4))) result.add(GROUP_WRITE); if (isX(perms.charAt(5))) result.add(GROUP_EXECUTE); if (isR(perms.charAt(6))) result.add(OTHERS_READ); if (isW(perms.charAt(7))) result.add(OTHERS_WRITE); if (isX(perms.charAt(8))) result.add(OTHERS_EXECUTE); return result; }
Java NIO2 UnmappableCharacterException
English follows Japanese.
- 以下のようにファイルの出力をNIOからNIO2に書き換えた場合、出力時の値によっては動作が違ってきます。
「Pokémon」を文字コードをsjisを指定してファイル出力する処理をNIOとNIO2で記述してみました。
- NIOの場合は、正常終了するのですが、出力したファイルは「Pock?mon」となっています。
- NIO2の場合は、UnmappableCharacterExceptionになります。
そもそも文字コードとして正しくない値を出力しているのが問題ではあるのですが、リファクタリングしたことで動作が違ってくるのは、、、
- When you refactor codes from Java NIO to NIO2 like below, you will have different results.
I implemented the function which writes the value [Pokémon] to the file with sjis Charset.
- When using NIO the method ended without Exception, but the result is Pock?mon.
- When using NIO2 the method ended with UnmappableCharacterException.
Basically it is wrong using mismatched Charset, but I did not expect to see the different result... :-(
- Sample.java
package com.sample; import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; public class Sample { public static void main(String... args) throws IOException { Sample sample = new Sample(); sample.writeNIO(); sample.writeNIO2(); } void writeNIO() { String val = "Pockémon"; try (BufferedWriter writer = new BufferedWriter( new OutputStreamWriter(new FileOutputStream("/Users/tomo/NIO.txt"), Charset.forName("sjis")))) { writer.write(val); } catch (IOException e) { e.printStackTrace(); } } void writeNIO2() throws IOException { String val = "Pockémon"; Path path = Paths.get("/Users", "tomo", "NIO2.txt"); try (BufferedWriter writer = Files.newBufferedWriter(path, Charset.forName("sjis"));) { writer.write(val); } } }
- SampleTest.java
package com.sample; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.nio.charset.UnmappableCharacterException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import org.junit.Before; import org.junit.Test; public class SampleTest { Sample sample; @Before public void setUp() throws Exception { sample = new Sample(); } @Test public void testWriteNIO() { sample.writeNIO(); Path path = Paths.get("/Users", "tomo", "NIO.txt"); boolean exists = Files.exists(path); assertTrue(exists); } @Test(expected = UnmappableCharacterException.class) public void testWriteNIO2() throws IOException { sample.writeNIO2(); } }
The code is here gist.github.com
Mail template sample
@bufferingsさんのセッションでThymeleaf3からtextでも使用できることを学んだので、ちょっと試してみました。
Sample.java
package com.sample; import java.io.IOException; import java.io.Writer; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.Locale; import java.util.stream.Collectors; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; import org.thymeleaf.templateresolver.FileTemplateResolver; public class Sample { public static void main(String... args) { Sample sample = new Sample(); sample.createMail(Locale.JAPAN); sample.createMail(Locale.US); } private void createMail(Locale locale) { Locale.setDefault(locale); Context context = new Context(); context.setVariable("mailTo", "Hanako"); // <- mail.template ${mailTo} List<String> bodies = Arrays.asList("body1", "body2", "body3"); context.setVariable("bodies", bodies); <- set bodies as ArrayList FileTemplateResolver resolver = new FileTemplateResolver(); resolver.setPrefix("resources/"); resolver.setTemplateMode(TemplateMode.TEXT); <- *** set mode TemplateEngine engine = new TemplateEngine(); engine.addTemplateResolver(resolver); Path path = Paths.get(String.format("mail_%s.txt", locale.getLanguage())); try (Writer writer = Files.newBufferedWriter(path);) { engine.process("mail.template", context, writer); } catch (IOException e) { e.printStackTrace(); } } }
mail.template
${mailTo}と${body}の部分は、変数になるので上記のcontextでkey,valueで設定
#{greeting}は、propertyファイルより設定されるので、上記のLocaleに依存して、日本語の場合は「mail_ja_jp.properties」英語の場合は英語用を作成していないのでデフォルトの「mail.properties」を使用
基本的にtemplateと同じ名前にしておくとデフォルトで使用できます。
To:[[${mailTo}]] [[#{greeting}]] [# th:each="body : ${bodies}"] [[${body}]] [/] from [[${#locale.country}]]
mail_ja_jp.properties
greeting=こんにちは
mail.properties
greeting=Hello
実行後のmail
- mail_ja.txt
To:Hanako こんにちは body1 body2 body3 from JP
- mail_en.txt
To:Hanako Hello body1 body2 body3 from US
build.gradle
apply plugin:'java' sourceSets { main { resources { srcDir 'resources' } } } repositories { mavenCentral() } sourceCompatibility=1.8 targetCompatibility=1.8 jar { manifest { attributes 'Main-class': 'com.sample.Sample' } } dependencies { compile 'org.thymeleaf:thymeleaf:3.0.0.RELEASE' }
- 可変の内容について
上記のbodyの部分は、改行コードを使って複数行の実装していますが、th:eachとかを使いたかったのですが、実装方法が?です(汗)
もしよければコメントお願いします!
早速@bufferingsさんからコメント頂いて訂正しました。ありがとうございます!
以下のサイトも参考にしました。
Thymeleaf 3 ten-minute migration guide - Thymeleaf
以下にアップしてます。
github.com