もしこのブログがお役に立ちましたら、次回のAmazonでのお買い物時に こちらのリンクから 購入していただけますと嬉しく思います。

ラベル プログラミング の投稿を表示しています。 すべての投稿を表示
ラベル プログラミング の投稿を表示しています。 すべての投稿を表示

2023年12月24日

Eclipseの「呼び出し階層を開く」(Open Call Hierarchy)が機能しなくなった場合

Eclipseをアップデートした場合などに、「呼び出し階層を開く」(Open Call Hierarchy)が機能しなくなることがあります。その場合には以下の手順で解決できます。

  1. Eclipseを終了する
  2. workspaceのフォルダーを開き、「.metadata」→「.plugins」→「org.eclipse.jdt.core」の順に開く
  3. 「savedindexnames.txt」と、「.index」拡張子のファイルをすべて削除する
  4. Eclipseを起動する
手元の環境では、表記の問題だけでなく、Stringで記述した完全修飾名(FQCN)のホバー機能(Ctrlキー+マウスオーバーで遷移できる機能)も動作するようになりました。

2021年7月19日

mysqlで「java.lang.IllegalArgumentException: HOUR_OF_DAY: 0 ->1」というエラーが出る

javaでMySQL Connector/J 8.0を使ってdate型カラムのデータを取得する際、
java.lang.IllegalArgumentException: HOUR_OF_DAY: 0 ->1
というエラーが出る場合があります。実はある特定の日付が格納されている場合にこのエラーが出ます。

特定の日付とはこちらの4つ。
1948-05-02 1949-04-03 1950-05-07 1951-05-06
何の日付かと言うと、過去に日本でサマータイムが導入されたことがある年のサマータイム開始日です。どうしてエラーが起きるかというと、1つ目の例で言うと、1948-05-02の00:00:00から00:59:59はこの世に存在しないからです。つまりdate型カラムで1948-05-02が格納されている場合、DBには1948-05-02 00:00:00に変換されるデータがありますが、その時間が当時の日本では存在しないのでエラーが出るわけです。

この場合、JDBCの接続URLを次のように修正する必要があります。
serverTimezone=Asia/Tokyo ↓ serverTimezone=GMT%2B9
このように、タイムゾーンIDではなくオフセットで指定するとサマータイムを認識させないで済みます。

2019年6月13日

【超簡単】Eclipseのコメント文字化けを直す方法

Windows10で2018年くらいから発生している問題です。

Eclipseでソースコードを開くとコメントだけ文字化け(豆腐化)します。
しかも、全部ではなくて前半部分。
例えば、「//その他」が「//□□他」となってしまいます。

原因はどうやらデフォルトのConsolasフォントが日本語文字セットに対応していないかららしいんですが、以前のEclipseではConsolasで表示できない文字はMSゴシックとかメイリオで表示できてましたよね?
Consolas以外のフォントは見づらいので、フォントの変更は何としても避けたい。

というわけで解決方法を探していたんですが、なんと、eclipse.exeをWindows8互換で起動すれば良いということが分かりました。
ネタ元はこちら。
https://bugs.eclipse.org/bugs/show_bug.cgi?id=536562#c22

Eclipse側で根本解決を見るまでは、この方法が最も簡単ではないかと思います。

2016年10月17日

content.php ではなく functions.php を使って抜粋を表示する

WordPress のトップ画面やアーカイブ画面で記事を一覧表示する場合、デフォルトでは本文全体が表示されてしまいます。
これを抜粋表示に変更する方法としてよく紹介されているのが、下記のように content.php の条件文を細工するという技です。

<?php if ( is_search() ) : ?>
<div class="entry-summary">
<?php the_excerpt(); ?>
</div><!-- .entry-summary -->
<?php else : ?>

上記1行目の if 文を下記に変更。

<?php if ( is_search() || is_home() || is_archive() ) : ?>

ただこれでは、テーマをアップデートするたびにファイルを修正しなければなりません。
そこで子テーマの出番になるわけですが、子テーマの functions.php に下記のコードを加えると、疑似的な抜粋表示が実現できます。
(もちろん、子テーマではなく通常の functions.php に追加しても動きます。)

function show_excerpt($the_content) {
    if (is_search() || is_home() || is_archive()) {
        return mb_substr(trim(preg_replace('/\s{2,}/', ' ', strip_tags($the_content))), 0, 55) . ' &hellip; <a href="' . get_permalink() . '">続きを読む &rarr;</a>';
    } else {
        return $the_content;
    }
}
add_filter('the_content', 'show_excerpt');

if 文の内側の文字列変換は下記のような順序で行っています。

  1. strip_tags($the_content) で本文のタグをすべて削除
  2. preg_replace('/\s{2,}/', ' ', $hoge) で2つ以上連続した空白文字を半角スペースに変換
  3. trim($hoge) で先頭と末尾の空白文字を削除
  4. mb_substr($hoge, 0, 55) で、the_excerpt() と同様、先頭の55文字を切り出し
  5. 文字列の末尾に「…」と記事へのリンクを追加

探した限り、この方法はどのサイトにも載っていなかったので、もしお役に立ちましたらコメントをいただけると嬉しいです。
なお、この方法と content.php を細工する方法とで、HTML タグの class が若干変わるようですので、適宜スタイルシートなども修正する必要があるかも知れません。

2013年6月5日

Windowsで「Fatal error: Call to undefined function ldap_connect()」が出る場合の対処法

php.iniには
extension=php_ldap.dll
と指定しているのに、なぜかタイトルのエラーが消えない場合があります。

こんな時に役立つのは、環境変数PathにPHPのフォルダを指定することです。
既存の文字列+セミコロン+フォルダです。
hogehoge;C:\php-5.4.15-Win32-VC9-x86\
Windowsの再起動も忘れないでください。

2012年3月26日

Mac Safariでダウンロードする日本語ファイル名の文字化け対策

タイトルの通りです。
URLに日本語ファイル名を付けなくても大丈夫です。
以下にJava Servletの例を挙げます。

Mac Safari
response.addHeader("Content-Disposition", "attachment; filename="
+ new String(fileName.getBytes(), "ISO-8859-1");
プログラム内部の文字コードでファイル名のバイト配列を取得し、ISO-8859-1でエンコードします。

ついでに他の例も挙げておきます。

Windows IE
response.addHeader("Content-Disposition", "attachment; filename="
+ URLEncoder.encode(fileName, "UTF-8");


Windows Firefox、その他?
response.addHeader("Content-Disposition", "attachment; filename*=UTF-8'ja'"
+ URLEncoder.encode(fileName, "UTF-8");

2011年10月8日

リフレクションとアノテーション

java.lang.reflect.Constructor、Field、Method
の親クラスの
java.lang.reflect.AccessibleObject

getAnnotation(Class annotationType)
とか
isAnnotationPresent(Class annotationType)
などというメソッドがあるわけですが、引数に独自アノテーションのクラスを指定しても期待通りの動作をしない場合があります。
そういう場合は、アノテーション定義の直前に一行加えます。
@Retention(RetentionPolicy.RUNTIME)
public @interface OwnAnnotation {
}
この
@Retention(RetentionPolicy.RUNTIME)
を指定すると、プログラム実行時にも独自アノテーションを参照できるようになるというわけです。

2011年9月21日

Velocityのmacroをキャッシュさせない

Apache Velocityのmacro(Velocimacro)をvmファイルやhtmlファイル内にインラインで定義したとします。
設定ファイルvelocity.propertiesが規定値のままだと、一度記述したmacroがキャッシュされて、開発に手間取る場合があります。
手元の環境の場合、velocity.propertiesの項目を以下のように設定することでキャッシュ問題を解消できました。
XXX.resource.loader.cache = false
velocimacro.permissions.allow.inline.to.replace.global = true
これで開発時にmacroを書き換えた場合、すぐに変更が反映されるようになると思います。

2011年7月6日

Eclipse 3.7 (Indigo) に Google App Engine Plugin を追加する

GAE のプラグインを Eclipse IDE for Java DevelopersEclipse Classic 3.7 にインストールしようとすると下のようなエラーが出ます。
必ず Eclipse IDE for Java EE Developers を使うようにしましょう。

ちなみに Install New Software から入力する URL は
http://dl.google.com/eclipse/plugin/3.7
です。

Cannot complete the install because one or more required items could not be found.
Software being installed: Google App Engine Java SDK 1.5.1 1.5.1.r37v201106211634 (com.google.appengine.eclipse.sdkbundle.e37.feature.feature.group 1.5.1.r37v201106211634)
Missing requirement: Google App Engine Plugin 2.3.2.r37v201106211634 (com.google.appengine.eclipse.core 2.3.2.r37v201106211634) requires 'bundle org.eclipse.wst.xml.core 0.0.0' but it could not be found
Cannot satisfy dependency:
From: Google App Engine SDK 1.5.1.r37v201106211634 (com.google.appengine.eclipse.sdkbundle 1.5.1.r37v201106211634)
To: bundle com.google.appengine.eclipse.core 0.0.0
Cannot satisfy dependency:
From: Google App Engine Java SDK 1.5.1 1.5.1.r37v201106211634 (com.google.appengine.eclipse.sdkbundle.e37.feature.feature.group 1.5.1.r37v201106211634)
To: com.google.appengine.eclipse.sdkbundle [1.5.1.r37v201106211634]

Cannot complete the install because one or more required items could not be found.
Software being installed: Google Plugin for Eclipse 3.7 2.3.2.r37v201106211634 (com.google.gdt.eclipse.suite.e37.feature.feature.group 2.3.2.r37v201106211634)
Missing requirement: Google Plugin for Eclipse 3.7 2.3.2.r37v201106211634 (com.google.gdt.eclipse.suite.e37.feature.feature.group 2.3.2.r37v201106211634) requires 'org.eclipse.wst.common.project.facet.core 0.0.0' but it could not be found

2011年7月4日

Servlet で 301 リダイレクト

サーバー移行などで URL が変更になった場合、リダイレクトには HTML の meta タグよりも .htaccess が有効だそうです。
ただ、GAE/J など .htaccess が使えない場合はどうするかというと、Servlet に 301 リダイレクトを実装すればいいわけです。

以下の例は元々の URL が
http://www.getore.info/blog/?[ページ番号を指定するクエリ]
だったのが
http://blog.getore.info/[自動生成のリンク]
に変更になった場合です。

public class RedirectServlet extends HttpServlet {
public void service(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
// 変換規則が無い場合は一つ一つマッピングするしかない
Map<String, String> map = new HashMap<String, String>();
map.put("p=404", "2011/06/radiko_714.html");
map.put("p=19", "2009/10/umssort_12.html");

String query = "";
if (req.getQueryString() != null) {
query = req.getQueryString();
}

String file = "";
if (map.containsKey(query)) {
file = map.get(query);
}

// 該当するページが無い場合はトップページに飛ぶ
String url = "http://blog.getore.info/" + file;

resp.setStatus(301);
resp.setHeader("Location", url);
resp.setHeader("Connection", "close");
}
}

何かの変換規則がある場合は、Map を使うのではなく、正規表現などで対応した方が手っ取り早いと思います。

そして、web.xml に上のサーブレットを追加します。
<servlet>
<servlet-name>Redirect</servlet-name>
<servlet-class>info.getore.RedirectServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Redirect</servlet-name>
<url-pattern>/blog/</url-pattern>
</servlet-mapping>

2010年11月17日

Velocityの変数名を動的に定義する

Apache Velocityで変数名は通常以下のように定義します。
(例の中の$listはjava.util.Listのインスタンスです)

#set($fruit0 = $list.get(0))
#set($fruit1 = $list.get(1))
#set($fruit2 = $list.get(2))


上の例のように、同じ種類の変数名がほぼ一緒の場合、何としてでもループ構文で書きたくなるのがプログラマの性です。
ただし、Velocityでは以下のようには記述できません。

#foreach($num in [0..2])
#set($fruit$num = $list.get($num))
#end


上の場合、「$fruit$num」という書き方が変数として認められないため、エラーが出ます。

ではどうしたら良いのかというと、以下のようにすれば解決できます。

#foreach($num in [0..2])
$request.setAttribute("fruit$num", $list.get($num))
#end


数ヶ月間ずっと悩んでいたのですが、意外と簡単に解決できてびっくりです。

2010年3月22日

PHPからIMAP操作

Gmailに送信用のアカウントを作ってPHPからGmail経由でメールを送信したとします。
もしかするとその後、送信済みのメールを削除したいと思うかもしれません。
その場合次のようなコードで対応できます。

注意1.Gmailの設定画面から言語を「English (US)」に設定しておく必要があります。
注意2.このコードを実行すると「Sent Mail(送信済み)」および「Trash(ゴミ箱)」フォルダの中身がすべて削除され、復元することはできません。

// pearのNet_IMAPを利用する
require_once('Net/IMAP.php');
require_once('Net/IMAPProtocol.php');

$imap = new Net_IMAP("ssl://imap.googlemail.com", 993);

// デバッグモードをOnにする
$imap->setDebug(true);

// ログインする
$imap->login("アカウント名@gmail.com", "パスワード");

// 「Sent Mail」フォルダを選択する
$imap->selectMailbox("[Gmail]/Sent Mail");

// 「Sent Mail」フォルダのメールを「Trash」フォルダに移動する
$imap->copyMessages("[Gmail]/Trash");

// 「Trash」フォルダを選択する
$imap->selectMailbox("[Gmail]/Trash");

// 「Trash」フォルダ内のすべてのメールに削除フラグを付ける
$imap->setFlags("all", "\Deleted", "add");

// ゴミ箱を空にする
$imap->expunge();

// IMAPサーバから切断する
$imap->disconnect();


はまったのは、「Sent Mail」フォルダ内で削除フラグをつけてもメールがゴミ箱に移動しないことでした。
Gmailサーバーは削除フラグをセットするコマンドを、当該メールをアーカイブするコマンドとみなすようです。
なので、まずメールを「Trash」フォルダに移動させ、そこで削除フラグを付け、最後にEXPUNGEコマンドを発行する必要があります。
こうすることでやっと、論理削除ではなく物理削除したことになるようです。

最後にNet_IMAPのAPIドキュメントのリンクを貼っておきます。

2010年3月15日

JavaのGenericsへの要望

ずっと開発に関わっているあるJavaベースのWebアプリがあるのですが、数ヶ月前にJREが1.4から5.0にアップデートされました。
今まで1.4準拠の構文ばかり使ってきたのですが、そろそろ5.0以降の構文にも慣れていかないといけないなぁと思い、今日試してみました。
Genericsを意識して使ってみたのですが、「型引数」を指定できるのは確かにバグを減らす効果があると思います。
ただ、「型引数」の影響範囲がsetterやgetterの類だけなのはいただけません。
例えば、ちょっと長いですが以下のようなコードを書いた場合です。

/**
* 標準入力を一行ずつ読み込み、足し算を行う
*/
public static void main(String[] args) {
// Listに型引数としてIntegerを指定する
List<Integer> inputNumbers = new ArrayList<Integer>();

Scanner scanner = new Scanner(System.in);
// 標準入力を一行ずつ読み込む
while (scanner.hasNext()) {
String inputText = scanner.next();
// "exit"と入力されたら標準入力の読み込みを終了する
if ("exit".equals(inputText)) {
break;
}
try {
// 数字の入力の場合のみListに追加する
inputNumbers.add(Integer.parseInt(inputText));
} catch (NumberFormatException e) {
System.out.println("数字を入力してください");
}
}

// ListにString変数の追加を試みる
inputNumbers.add("1"); // ←コンパイルエラー

// ListにStringの"1"が含まれるかチェックする
if (inputNumbers.contains("1")) { // ←コンパイルが通る
System.out.println("文字列の1が入力されました"); // ←このコードが実行されることはあり得ない
}

// ListにIntegerの"1"が含まれるかチェックする
if (inputNumbers.contains(1)) {
System.out.println("数値の1が入力されました"); // ←このコードが実行されることはあり得る
}

int sum = 0;
for (int number : inputNumbers) {
sum += number;
}
System.out.println("合計値 : " + sum);
}


25行目はコンパイルエラーが出るにも関わらず、28行目のコードは問題ありません。
例えば稀な例かも知れませんが、DBから読み出した数値をString型のまま扱ってしまった場合に、ListやMapの存在チェックのメソッドにその変数を渡してもtrueが返らない、なんてことが考えられます。
もし上の例の28行目のような場面でコンパイルエラーが出ればそのようなバグは防げます。
調べたところJava6.0でも同じ仕様のようですので、今後のバージョンでどうなるか見守りたいです。

2010年3月5日

リモートファイルのエディター「ecoder」

サーバー上のソースコード等をブラウザーで編集できるエディターを見つけました。

ecoder

日本語だと「イーコーダー」って読むんでしょうね、きっと。

今までPHPなどのスクリプトは
1.ローカルで編集
2.FTPでサーバーにアップロード
3.ブラウザーで動作確認
という流れを踏む必要がありましたが、このエディターを使うと1と2の作業をまとめられます。
実際に使ってみましたが、とても便利で、デバッグの時間をかなり短縮できます!

注意点は、
・Basic認証などを施してアクセス制限する
・ファイルが編集できない場合、パーミッションを確認する
・ローカルに最新の更新を反映する方法を考える(都度、FTPでダウンロード?)
でしょうか。

いずれにしても、とても便利なWebアプリなので、今後のバージョンアップに期待です。

2010年3月4日

リッチWebアプリをJavaで。「Vaadin」

CodeZineで面白い記事を見つけました。

Javaで軽快に使える「軽量フレームワーク」特集 ~リッチなGUIを構築する「Vaadin」(1)

サンプルはこちらから。

Javaの知識があればこのフレームワークを使って、HTMLやDOM、Ajaxの知識なしにWebアプリケーションが作れるようです。
サンプルを見る限り、GoogleDocsのようなリッチアプリも作れてしまう感じです。

記事の最後にある一文が興味深いです。

プログラマは、ただごく普通のスタンドアロンなGUIアプリケーションを作るのとまったく同じ感覚でプログラムを作ればいいのです。


今までのWebアプリ開発の常識を覆してしまいそうですね。