Bad configurationエラーでGAEにデプロイできなかった原因と対策
GAEにデプロイしようとしたら、こんなエラー。
Bad configuration: Received SAXException parsing the input stream. Caused by: 途中でファイルの末尾に達しました。
ログを見ろって書いてあるので確認したら、WEB-INF/appengine-generated/datastore-indexes-auto.xml に問題があるらしい。
パス名のとおり、自動生成されるファイルなのになぜ!
そのファイルを開いてみると、何も書かれてない。
もしかして、XMLなのに中身がないから怒ってる?
ファイルを削除してデプロイしなおしたら、あっさりデプロイできた。
が、ローカルのデータストアに登録してた内容が消えてしまった。
(´・ω・`)
SQLSTATE[HY000]: General error: 1813 Tablespace for table '`hoge`.`hoge`'; exists. Please DISCARD the tablespace before IMPORT.
slim3のsortInMemory()の挙動が変?
データストアからエンティティを取得して、sortInMemory()でcreateDate.descでソートしたら、なぜか最新のいくつかのエンティティが結果に出てこない。
なぜ?
自作 Comparatorでソートしたらちゃんと最新のエンティティもでてくるんだけど。
なぜ?
List<Hoge> list = Datastore.query(meta).asList(); Collections.sort(list, new Comparator<Hoge>() { @Override public int compare(Hoge h1, Hoge h2) { long t1 = h1.getCreateDate() != null ? h1.getCreateDate().getTime() : -1; long t2 = h2.getCreateDate() != null ? h2.getCreateDate().getTime() : -1; if (t1 > t2) return -1; if (t1 < t2) return 1; return 0; } });
App Engineローカル開発サーバーのデータの場所
ローカル開発サーバーのデータが消えてしまったので、TimeMachineで過去からコピーしてくることに。
データの場所はどこかというと、Googleの公式ドキュメント
≫ Java 開発サーバー | Java の App Engine スタンダード環境 | Google Cloud
によると、
(project-dir)/war/WEB-INF/appengine-generated/local_db.bin
にあるらしい。
でも、そこにはない。
どこにあるのー?
ぐぐっても答えは見つからず。
自分のディレクトリのどこかにあるだろうと、findで探してみる。
$ find ~/ -type f -name local_db.bin -print
過去に作ったGAEアプリの local_db.bin がいっぱい出てくる出てくる。
しかし、ひとつだけ違う場所に!
ここにありました。
ls -l ~/Documents/workspace-oxygen/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/(project-name)/WEB-INF/appengine-generated/
local_db.bin だけでなく、Cloud Storageにアップロードしたファイルが、キーがそのままファイル名で保存されてる。
Google Cloud Storageに保存した画像をリサイズして応答する方法
最近はスマートフォンで撮影できる画像の解像度が巨大化してるので、そのままを表示すると遅くなってしまう。
そこで、リクエストパラメータにwidthを追加して、任意のサイズで表示できるようにした。
ここではblobKeyを元にBlobInfoを求めてるけど、ファイル名を元にしたい場合は makeImageFromFilename()でも可能。
≫ ImagesServiceFactory(Google App Engine API for Java) | Java の App Engine スタンダード環境 | Google Cloud
String key = request.getParameter("key"); String width = request.getParameter("width"); int w = 1024; try { w = Integer.parseInt(width); } catch (Exception e) {} BlobKey blobKey = new BlobKey(key); BlobInfo info = new BlobInfoFactory().loadBlobInfo(blobKey); Image image = ImagesServiceFactory.makeImageFromBlob(blobKey); Transform tf = ImagesServiceFactory.makeResize(w, w); Image resized = ImagesServiceFactory.getImagesService().applyTransform(tf, image); byte[] data = resized.getImageData(); String contentType = info.getContentType(); if (contentType == null || contentType.isEmpty()) { response.setContentType("application/octet-stream"); } else { response.setContentType(contentType); } response.setContentLength(data.length); ServletOutputStream os = response.getOutputStream(); os.write(data);