Mavenの起動時にエラーが出たのでメモ
エラーメッセージ
1 2 | $ mvn package メイン・クラスorg.codehaus.plexus.classworlds.launcher.Launcherが見つからなかったかロードできませんでした |
対応方法
こちらを参考に
1 2 | $ unset M2_HOME $ mvn package |
Mavenの起動時にエラーが出たのでメモ
1 2 | $ mvn package メイン・クラスorg.codehaus.plexus.classworlds.launcher.Launcherが見つからなかったかロードできませんでした |
こちらを参考に
1 2 | $ unset M2_HOME $ mvn package |
Pythonで並列化させたプログラムを走らせていたのですがあまりの遅さにJavaへと変更した際、並列化をomp4jで簡単にできたのでメモ。
OpenMPの説明は、Wikipediaをみてもらうことにして、ソースコード中にコメントを書いておいて、コンパイルをすれば並列化プログラムの出来上がるという便利なライブラリ。
ここからJarファイルをダウンロードします。
1 | wget https://github.com/omp4j/omp4j/releases/download/v1.2/omp4j-1.2.jar |
簡単なプログラムを作成します。スレッド5で10回計算しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | import java.util.Random; public class OmpTest { private void run() { try { // omp parallel for threadNum(5) for (int i = 0; i < 10; i++) { new Task1(i).call(); } } finally { System.out.println("ThreadTest:finish"); } } static class Task1{ private int number; Task1(int number){ this.number=number; } public Long call() { System.out.println("Task1.start:"+this.number); long sleep=new Random().nextInt(10)*1000; long sum = 0; for (int i = 1; i <= 100 * 10000; i++) { sum += i; } try{ Thread.sleep(sleep); }catch(Exception e){} System.out.println("Task1.end:"+this.number+",sleep="+sleep); return sum; } } public static void main(String[] argv){ new OmpTest().run(); } } |
普通にコンパイルします。シングルスレッドで動作します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | $ javac OmpTest.java $ java OmpTest Task1.start:0 Task1.end:0,sleep=3000 Task1.start:1 Task1.end:1,sleep=2000 Task1.start:2 Task1.end:2,sleep=1000 Task1.start:3 Task1.end:3,sleep=0 Task1.start:4 Task1.end:4,sleep=5000 Task1.start:5 Task1.end:5,sleep=6000 Task1.start:6 Task1.end:6,sleep=9000 Task1.start:7 Task1.end:7,sleep=3000 Task1.start:8 Task1.end:8,sleep=8000 Task1.start:9 Task1.end:9,sleep=2000 ThreadTest:finish |
シリアルに計算されているのがわかります。
並列化できるようにコンパイルします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | $ java -jar omp4j-1.2.jar OmpTest.java $ java OmpTest Task1.start:3 Task1.start:1 Task1.start:2 Task1.start:4 Task1.start:0 Task1.end:1,sleep=0 Task1.start:5 Task1.end:0,sleep=3000 Task1.start:6 Task1.end:2,sleep=3000 Task1.end:5,sleep=3000 Task1.start:7 Task1.start:8 Task1.end:3,sleep=4000 Task1.start:9 Task1.end:4,sleep=7000 Task1.end:9,sleep=3000 Task1.end:6,sleep=8000 Task1.end:8,sleep=8000 Task1.end:7,sleep=9000 ThreadTest:finish |
並列に計算できているのがわかります。
実際にはコンパイル時にコードを変換してコンパイルしています。
ここにソースコードを貼り付けると変換後のソースが表示されます。上記サンプルだとエラーになってしまいましたが、簡単なコードならばそのコードが表示されます。
簡単にJavaのコードが並列化できます。色々と制約はありますが(変数関連など)、簡単に並列プログラムが作成できるのはメリットでしょう。
ポイントは2回InputStreamを作成することです。
http://stackoverflow.com/questions/8351886/amazons3-putobject-with-inputstream-length-example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | package awssample; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.sql.SQLException; import com.amazonaws.ClientConfiguration; import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.PutObjectRequest; import com.amazonaws.util.IOUtils; public class S3Write { private static String endpoint = "https://s3-ap-northeast-1.amazonaws.com"; public static void main(String[] args) throws SQLException { String s = "2011-01-01,9999,1,100,1.0,-1.0,0.5"; // 認証オブジェクトを作成 String accessKey = "xxxxxx"; String accessSecretKey = "xxxxxxxx"; AWSCredentials credentials = new BasicAWSCredentials(accessKey, accessSecretKey); // ConfigurationでTimeout時間を30秒に設定 ClientConfiguration clientConfiguration = new ClientConfiguration(); clientConfiguration.setConnectionTimeout(30000); // AmazonS3Clientをインスタンス化 AmazonS3Client s3 = new AmazonS3Client(credentials, clientConfiguration); s3.setEndpoint(endpoint); try { InputStream is = new ByteArrayInputStream(s.getBytes("UTF-8")); byte[] contentBytes = IOUtils.toByteArray(is); Long contentLength = Long.valueOf(contentBytes.length); System.out.println("contentLength=" + contentLength + ",s=" + s); ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentLength(contentLength); // isではなく new ByteStreamInputStreamでもう一度さくせいしたものを渡す s3.putObject(new PutObjectRequest("bucketname", "path/to/file.txt", new ByteArrayInputStream(s.getBytes("UTF-8")), metadata)); } catch (Exception e) { e.printStackTrace(); } } } |
ちょっと以前まではEclipseの逆コンパイラ、JD-EclipseのインストールにはUpdateサイトから行っていたのですが、Lunaでインストールした際にはまったので以下にメモ。
http://totech.hateblo.jp/entry/2015/02/19/145004
こちらに書いてあるようにhttp://jd.benow.ca/jd-eclipse/updateのupdateサイトをHelpのInstallNewSoftwareからインストールするとJD-Eclipseの0.1.5というバージョンがインストールされます
これを使用し、デコンパイルしようとしてもうまくデコンパイルされません。最初はFileassociationがおかしいのか?と思い設定を見直したのですがClassFileEditorのまま、特におかしなところはありません。
ずいぶん悩んだのですが、JD-Eclipseのサイトに書いてある手順がファイルからインストールしろとのことなのでその通りにします
https://github.com/java-decompiler/jd-eclipse
こちらからjd-eclipse-site-1.0.0-RC2.zipをダウンロード
https://github.com/java-decompiler/jd-eclipse/releases
EclipseのヘルプーInstallNewSoftwareのAddからArchiveを選択、先ほどのZIPファイルを選択しインストール。
インストールすると1.0.0のバージョンがインストールされます。
FileAssociationもJD Class FileViewerとなります。
これでclassファイルを選択するとめでたく逆コンパイルされます。
古いバージョンのJD-EclipseはJava8には対応していないのでしょうか。。
いつも忘れてしまうのでメモ
brew install tomcat7
oracle jdkをインストールし、シンボリックリンク
$ which java
/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home//bin/java
EclipseのClassicをインストールするとサーバランタイムがインストールされずに、TOMCATアプリなど作成する際にデバッグに困ってしまいます。
サーバランタイムをインストールするには、予めBrewでTomcatをインストールした後に、ヘルプのinstall new softwareから
を選択し、いかの2つのプラグインをインストールします。
その後、環境設定ーServerーRuntimeEnvironmentsのaddでtomcatを追加するのですが、この際にディレクトリに以下を入力します
/usr/local/Cellar/tomcat7/7.0.55/libexec
これでサーバランタイムが設定可能となります。
この辺りの内容はこちらから引用しています
SQLiteにはストアドプロシージャはなく、その代わりにユーザ定義関数を追加し、同様の処理を行うようにできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class TestFunc extends Function{ @Override protected void xFunc() throws SQLException { try{ String a = value_text(0); String b = value_text(1); result(Integer.parseInt(a)+Integer.parseInt(b)); }catch(Exception e){ throw new SQLException(e.getMessage()); } } } |
org.sqlite.Functionを継承したクラスを作成し、その中のxFuncをオーバラードしたメソッで実装する関数を定義しresultで戻します。
今回の場合には文字列で定義した数字を足しあわせて返すという関数を定義しました。
これを利用する際にはJDBCのコネクションに対しFunction.createでバインドしてやります
1 2 3 4 5 6 7 8 9 10 11 12 13 | InitialContext ic = new InitialContext(); DataSource ds = (DataSource)ic.lookup("java:comp/env/test"); Connection conn=ds.getConnection(); conn.setAutoCommit(false); Function.create(conn,"my_func",new TestFunc()); PreparedStatement stmt=conn.prepareStatement("select my_func(?,?)"); stmt.setString(1,"1"); stmt.setString(2,"3"); ResultSet rs=stmt.executeQuery(); while(rs.next()){ out.println(rs.getString(1)); } |
バインドする際にSQL文内で呼ぶ関数名を同時に定義します。その後は通常のJDBCの処理と同じです。
DBCPで使うサンプルです
1 2 3 4 5 6 7 8 | <Resource name="test" auth="Container" type="javax.sql.DataSource" driverClassName="org.sqlite.JDBC" url="jdbc:sqlite:C:\\temp\\test.db" accessToUnderlyingConnectionAllowed = "true" factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory" /> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | public class TestServlet extends HttpServlet{ private static final long serialVersionUID = 1L; @Override public void init(ServletConfig sc) throws ServletException { super.init(sc); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { doPost(req, res); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html;charset=utf-8"); PrintWriter out=res.getWriter(); //http://stackoverflow.com/questions/6489514/apache-commons-dbcp-connection-object-problem-thread-classcastexception-in-org //http://www.ksky.ne.jp/~snbhsmt/commons-dbcp.html //http://grokbase.com/t/tomcat/users/052spdat5s/tomcat-5-5-7-using-builtin-jdbc-connection-pool-cant-access-real-connection-accesstounderlyingconnectionallowed-true try{ InitialContext ic = new InitialContext(); BasicDataSource ds = (BasicDataSource)ic.lookup("java:comp/env/test"); //ds.setAccessToUnderlyingConnectionAllowed(true); DelegatingConnection dcon=(DelegatingConnection)ds.getConnection(); DelegatingStatement dstmt = (DelegatingStatement)dcon.createStatement(); PoolableConnection pconn=(PoolableConnection)dstmt.getDelegate().getConnection(); Connection conn=pconn.getInnermostDelegate(); conn.setAutoCommit(false); Function.create(conn,"my_func",new TestFunc()); PreparedStatement stmt=conn.prepareStatement("select my_func(?,?)"); stmt.setString(1,"1"); stmt.setString(2,"3"); ResultSet rs=stmt.executeQuery(); while(rs.next()){ out.println(rs.getString(1)); } dcon.close();// 140916 閉じ忘れるとTOMCAT起動時に止まる }catch(Exception e){ e.printStackTrace(); } } public class TestFunc extends Function{ @Override protected void xFunc() throws SQLException { try{ String a = value_text(0); String b = value_text(1); result(Integer.parseInt(a)+Integer.parseInt(b)); }catch(Exception e){ throw new SQLException(e.getMessage()); } } } } |
ここでのポイントはDBCPのコネクションプールからJDBCのコネクションを取得する際に実際のコネクションを取得してやる必要があります。
1 2 3 4 5 6 7 8 | BasicDataSource ds = (BasicDataSource)ic.lookup("java:comp/env/test"); //ds.setAccessToUnderlyingConnectionAllowed(true); DelegatingConnection dcon=(DelegatingConnection)ds.getConnection(); DelegatingStatement dstmt = (DelegatingStatement)dcon.createStatement(); PoolableConnection pconn=(PoolableConnection)dstmt.getDelegate().getConnection(); Connection conn=pconn.getInnermostDelegate(); |
この部分です。詳細は↓あたりを参考にしてください。
http://www.ksky.ne.jp/~snbhsmt/commons-dbcp.html
なおJDBCはsqlite-jdbc-3.7.2.jarではなくsqlite-jdbc-3.8.5-pre1.jarを使用してください。Function.create内のinstanceofでconnectionが実コネクションかどうか判定しているのですが、JDBCが古いほうだと何故かここでエラーになってしまいます。
こんな感じでSQLite+DBCPでユーザ定義関数が追加できます。参考になれば幸いです
DelegateingConnectionを取得した際にコネクションを閉じ忘れるとTOMCAT起動時にエラーというか無限ループに陥ります。注意
文字列からEnum型へ変換するサンプルです
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public class test{ public static enum Channel{PC,WEB; static Channel get(String s){ Channel[] channels=Channel.values(); for(Channel channel:channels){ if(channel.toString().equals(s))return channel; } return null; } }; public static void main(String[] argv){ System.out.println(Channel.WEB); // Enumをそのまま出力 System.out.println(Channel.get("PC")); // 文字列からEnumを取得してみる } } |
機械学習用のライブラリ、ApacheMahoutを使用していてちょっと困ったのでメモ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import java.io.*; import java.util.*; import org.apache.mahout.cf.taste.impl.model.file.FileDataModel; import org.apache.mahout.cf.taste.model.DataModel; import org.apache.mahout.cf.taste.recommender.*; import org.apache.mahout.cf.taste.impl.recommender.GenericItemBasedRecommender; import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity; import org.apache.mahout.cf.taste.similarity.ItemSimilarity; class test{ public static void main(String[] argv){ try{ DataModel model=new FileDataModel(new File("test.csv")); ItemSimilarity similarity=new PearsonCorrelationSimilarity(model); Recommender recommender= new GenericItemBasedRecommender(model,similarity); List<RecommendedItem> recommendations=recommender.recommend(1,5); for(RecommendedItem recommendation:recommendations){ long recommendCode=recommendation.getItemID(); System.out.println(recommendCode); } }catch(Exception e){} } } |
こんなかんじでアイテムベースのレコメンドを作成していたのですが、CSVファイルを読み込んだ際に
1 2 3 4 5 6 7 8 | java.util.NoSuchElementException at com.google.common.base.AbstractIterator.next(AbstractIterator.java:75) at org.apache.mahout.cf.taste.impl.model.file.FileDataModel.processLine(FileDataModel.java:384) at org.apache.mahout.cf.taste.impl.model.file.FileDataModel.processFile(FileDataModel.java:340) at org.apache.mahout.cf.taste.impl.model.file.FileDataModel.buildModel(FileDataModel.java:239) at org.apache.mahout.cf.taste.impl.model.file.FileDataModel.reload(FileDataModel.java:208) at org.apache.mahout.cf.taste.impl.model.file.FileDataModel.<init>(FileDataModel.java:194) at org.apache.mahout.cf.taste.impl.model.file.FileDataModel.<init>(FileDataModel.java:149) |
こんなエラーが出て進まない時がある。実行したのはLinux64Bit環境のjdk1.6。
同じものをwindows7のjdk1.6で動かしてもエラーが出ない。。。
読み込んだCSVは600万行程度
よくわからないのですがCSVの最後に改行を入れるとエラーなく動作。
わけわからん
ちょっと困ったのでメモ
通常JavaのInetAddress.getLocalHost().getHostAddress()から取得できるIPアドレスは127.0.0.1
これではちょっと使えません
ネットワークインターフェースを調べるとちゃんとした?IPアドレスが取得できます
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import java.net.*; import java.util.*; public class test{ public static void main(String[] argv)throws Exception{ Enumeration<NetworkInterface> n = NetworkInterface.getNetworkInterfaces(); while (n.hasMoreElements()){ NetworkInterface e = n.nextElement(); Enumeration<InetAddress> a = e.getInetAddresses(); while ( a.hasMoreElements()){ InetAddress addr = a.nextElement(); if (!addr.getHostAddress().equals("127.0.0.1")) System.out.println(addr.getHostAddress()); } } } } |
意外とわからなかったのでメモ。