endokのブログ

IT・プログラミングネタ

Springで定義済のBean名一覧を出力する

SpringBootはSpringのBean設定を隠蔽してくれているのだが、SpringBoot側で定義しているBeanをInjectionしたいときにはどういったBeanが定義済なのかわからず困る。
定義済のBean名をすべて出力する方法を調べたのでメモ。

方法は下記の通り。

1. BeanFactoryAwareをimplementsして、BeanFactoryを取得する。
2. BeanFactoryをDefaultListableBeanFactoryにキャストして、getBeanDefinitionNamesメソッドを利用する。

Controllerで実装した場合の例はこのようになる。

@Controller
public class HelloController implements BeanFactoryAware {

	private DefaultListableBeanFactory beanFactory;
	
	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		this.beanFactory = (DefaultListableBeanFactory)beanFactory;
		
	}

	@RequestMapping(value = "/page1")
	public String page1() {
		
		for (String name : beanFactory.getBeanDefinitionNames()) {
			System.out.println(name);
		}
		
		return "page1";
	}
	
}

Spring Boot触ってみる その3 ーThymeleaf Layout Dialectでレイアウトを共通化ー

Spring Boot触ってみる その2 ーController,テンプレートエンジン(Thymeleaf)ー - endokのブログ
の続き。

Thymeleafにもincludeなどを使った共通化の仕組みはあるが、
各ページごとにincludeは書きたくない・・・。
Tilesのように共通レイアウトを定義する仕組みはないものかと調べたところ、
Thymeleaf Layout Dialect(https://github.com/ultraq/thymeleaf-layout-dialect)というものがあったため試してみる。

その1(http://endok.hatenablog.com/entry/2016/06/04/124011)で作成したサンプルプロジェクトを引き続き利用する。

続きを読む

SpringBootの開発に自動リロード(ホットデプロイ)を導入する

目次

  • 目次
  • はじめに
  • SpringLoaded
    • 特徴
    • 導入方法
  • Spring Boot Dev Tools
    • 特徴
    • 導入方法
  • まとめ

はじめに

SpringBootの開発の流れは、

1. コードを書く
2. [Run As]→[Spring Boot App]で起動
3. 動作確認する
4. コードを書く
5. Consoleから起動中のアプリをTerminate
6. [Run As]→[Spring Boot App]で起動
7. 3に戻る

としていたが、

いちいち修正を反映するのに停止して起動するのは煩わしい。
1つ処理を書くたびに動作確認したいタイプなので、開発効率が悪くなってしまう。

S2Containerにはホットデプロイあって楽だったなぁ・・・と思ったので同様の仕組みを調べてみた。

Springという名前が付いているし、JRebelは商用(myJRebelというフリー版もあるようだが)なので、SpringLoadedとSpringBootDevToolsを試してみる。

続きを読む

SpringToolSuiteでpom.xmlのdependencyを追加しても実行時に認識されない

SpringBootでDBアクセスをしようとしていたときのこと。

pom.xmlに下記記述を追加した。

	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-data-jpa</artifactId>
	</dependency>
	<dependency>
		<groupId>org.hsqldb</groupId>
		<artifactId>hsqldb</artifactId>
		<scope>runtime</scope>
	</dependency>

Repositoryクラスを作って下記のようにinjectionしてみるが、実行時にエラーが発生する。

	@Autowired
	MemberRepository repository;

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.dataSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).

>Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath.
ということで、組み込みDBであればクラスパスに配置さえしていれば問題なさそうである。
今回pom.xmlhsqldbを追加しているため、クラスパスは通っているはず。
を外してみるなど試行錯誤するも変わらず同じエラーが出続けた。

同じような症状をググっていき、最終的には
maven - Error running Basic Spring Batch example - Caused by: java.lang.ClassNotFoundException: org.hsqldb.jdbcDriver - Stack Overflow
に記載のあった、
>learing my entire local repository and then rebuilding has fixed the problem
を試したら解消した。

具体的には、Mavenのローカルレポジトリ内のファイルをすべて消したあとに再度実行すると解消していた。(ソースコードや設定は変更なし)
Mavenのローカルレポジトリの場所はPreferencesの[Maven]→[User Settings]のLocal Repositoryにパスが書いてある。

EclipseMavenを利用した際に起きるようだが、こういったキャッシュ周り?の問題は非常に原因が掴みづらくて困る。

Spring Boot触ってみる その2 ーController,テンプレートエンジン(Thymeleaf)ー

Spring Boot触ってみる その1 ー環境構築・サンプルプロジェクト作成ー - endokのブログ
の続き。

Controller作成と、Thymeleafを使ったテンプレート描画部分を確認する。
Spring BootではJSPではなくThymeleafの方がベタな模様。
(他のJava製Webフレームワークではどうなんでしょう)

前回作成したサンプルプロジェクトを引き続き利用する。

続きを読む

Spring Boot触ってみる その1 ー環境構築・サンプルプロジェクト作成ー

いまJavaでWebアプリケーションを作るならSpring Boot(http://projects.spring.io/spring-boot/)らしいという話を聞き、触ってみることに。

まずは環境構築とサンプルプロジェクトの作成。

続きを読む

Vagrantで独自BOX作成してATLASで公開する

やりたいこと

  • chef/centos-6.5 をベースにyum update、yum groupinstall Development ToolsしたBOXを作る。
  • Atlas by HashiCorp で公開してVagrantfileで指定できるようにする。

環境

最終的な手順

いろいろ問題は発生したが、最終的な手順は下記となった。

※ $ 〜はホストでのコマンド。> 〜はVM内でのコマンド。

ベースにするboxを使って普通にvagrant upする

今回の場合、Vagrantfileに下記のようにベースのboxを指定し、vagrant upする。

config.vm.box = "chef/centos-6.5"

vagrant sshして変更を加える

$ vagrant ssh
> sudo yum update -y
> sudo yum groupinstall -y 'Development Tools'

vagrantユーザーのinsecure private keyを配置する

vagrantユーザーのデフォルト公開鍵があり、それを設定しておく必要があった。

https://github.com/mitchellh/vagrant/tree/master/keys
vagrant.pubをvagrantユーザーのauthorized_keysに設定する。

> wget https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub
> cat vagrant.pub >> /home/vagrant/.ssh/authorized_keys
> rm vagrant.pub

kernelをアップデートした場合はVirtualBox Guest Additionsの再セットアップする

kernelをアップデートすると、vagrant up した際に下記のようなエラーが出る。

Failed to mount folders in Linux guest. This is usually because
the "vboxsf" file system is not available. Please verify that
the guest additions are properly installed in the guest and
can work properly. The command attempted was:

mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3` vagrant /vagrant
mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant` vagrant /vagrant

The error output from the last command was:

/sbin/mount.vboxsf: mounting failed with the error: No such device

vagrant-vbguestプラグインで再セットアップする。
自分の場合、通常時は使わないのでセットアップが終わったら削除しておく。

$ vagrant plugin install vagrant-vbguest
$ vagrant vbguest
$ vagrant plugin uninstall vagrant-vbguest

参考: VagrantのboxのGuest Additionsのアップデート方法 - Qiita

NICマッピングを消す

参考: Vagrant で作った仮想マシンから Box ファイルを作りなおす | CUBE SUGAR STORAGE

> sudo ln -s -f /dev/null /etc/udev/rules.d/70-persistent-net.rules

ログアウト後、Vagrantのinsecure key置き換え機能をOFFにする

VMからログアウトする。

> exit

設定したinsecure keyが置き換えられないように、Vagrantfileで機能をOFFにする。

config.ssh.insert_key = false

停止、パッケージングする

$ vagrant halt
$ vagrant package

package.boxというファイルが出来上がる。

出来上がったboxファイルを使ってみる

BOXを登録する。

$ vagrant add mycentos package.box

既存のVM破棄後、登録したBOXを起動する。

$ vagrant destroy
$ vi Vagrantfile
  config.vm.box = "mycentos"
$ vagrant up

vagrant sshして問題ないか確認する。

ATLASで公開する

  1. ATLASにログインし、Developmentページを開く
  2. "Create a Vagrant Box"のBeginボタンを押す
  3. BOX名、説明など入力し、BOX作成する
  4. "New Box Version"にバージョンと説明を入力してCreate versionボタンを押してバージョンを作成する
  5. "Providers"欄のCreate new providerボタンを押す
  6. Providerには「virtualbox」と入力し、Uploadを選択してpackage.boxをアップロードする。Providerが登録される
  7. Overviewページに戻り、バージョンのEditボタンを押す。
  8. 上の方に「This version hasn't been released.〜」と出ているので、Release versionボタンを押す

これで外部からアクセス可能になる。

Vagrantfileで

config.vm.box = "[アカウント名]/[BOX名]"

を指定すれば使える。