diff --git a/app/src/main/java/org/ethereum/android_app/MainActivity.java b/app/src/main/java/org/ethereum/android_app/MainActivity.java index c2ad4924..9fbac52a 100644 --- a/app/src/main/java/org/ethereum/android_app/MainActivity.java +++ b/app/src/main/java/org/ethereum/android_app/MainActivity.java @@ -80,6 +80,12 @@ public class MainActivity extends ActionBarActivity { return super.onOptionsItemSelected(item); } + @Override + protected void onDestroy() { + super.onDestroy(); + ethereumManager.onDestroy(); + } + // The definition of our task class private class PostTask extends AsyncTask { diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/EthereumManager.java b/ethereumj-core-android/src/main/java/org/ethereum/android/EthereumManager.java index fbd655ac..644237f4 100644 --- a/ethereumj-core-android/src/main/java/org/ethereum/android/EthereumManager.java +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/EthereumManager.java @@ -2,6 +2,8 @@ package org.ethereum.android; import android.content.Context; +import com.j256.ormlite.android.apptools.OpenHelperManager; + import org.ethereum.android.di.modules.EthereumModule; import org.ethereum.android.di.components.DaggerEthereumComponent; import org.ethereum.config.SystemProperties; @@ -57,4 +59,8 @@ public class EthereumManager { jsonRpcServer.start(); } + public void onDestroy() { + OpenHelperManager.releaseHelper(); + } + } diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/db/BlockDatabaseHelper.java b/ethereumj-core-android/src/main/java/org/ethereum/android/db/BlockDatabaseHelper.java deleted file mode 100644 index 45aa8c3b..00000000 --- a/ethereumj-core-android/src/main/java/org/ethereum/android/db/BlockDatabaseHelper.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.ethereum.android.db; - - -import java.sql.SQLException; - -import android.content.Context; -import android.database.sqlite.SQLiteDatabase; -import android.util.Log; - -import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper; -import com.j256.ormlite.dao.Dao; -import com.j256.ormlite.support.ConnectionSource; -import com.j256.ormlite.table.TableUtils; - -import org.ethereum.db.BlockVO; - -/** - * Database helper class used to manage the creation and upgrading of your database. This class also usually provides - * the DAOs used by the other classes. - */ -public class BlockDatabaseHelper extends OrmLiteSqliteOpenHelper { - - private static final String DATABASE_NAME = "blocks.db"; - private static final int DATABASE_VERSION = 1; - - // the DAO object we use to access the SimpleData table - private Dao blockDao = null; - - public BlockDatabaseHelper(Context context) { - super(context, DATABASE_NAME, null, DATABASE_VERSION); - } - - /** - * This is called when the database is first created. Usually you should call createTable statements here to create - * the tables that will store your data. - */ - @Override - public void onCreate(SQLiteDatabase db, ConnectionSource connectionSource) { - try { - Log.i(BlockDatabaseHelper.class.getName(), "onCreate"); - TableUtils.createTable(connectionSource, BlockVO.class); - } catch (SQLException e) { - Log.e(BlockDatabaseHelper.class.getName(), "Can't create database", e); - throw new RuntimeException(e); - } - } - - /** - * This is called when your application is upgraded and it has a higher version number. This allows you to adjust - * the various data to match the new version number. - */ - @Override - public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion) { - try { - Log.i(BlockDatabaseHelper.class.getName(), "onUpgrade"); - TableUtils.dropTable(connectionSource, BlockVO.class, true); - // after we drop the old databases, we create the new ones - onCreate(db, connectionSource); - } catch (SQLException e) { - Log.e(BlockDatabaseHelper.class.getName(), "Can't drop databases", e); - throw new RuntimeException(e); - } - } - - /** - * Returns the Database Access Object (DAO) for our SimpleData class. It will create it or just give the cached - * value. - */ - public Dao getBlockDao() throws SQLException { - if (blockDao == null) { - blockDao = getDao(BlockVO.class); - } - return blockDao; - } - - /** - * Close the database connections and clear any cached DAOs. - */ - @Override - public void close() { - super.close(); - blockDao = null; - } -} diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/db/BlockStoreDatabase.java b/ethereumj-core-android/src/main/java/org/ethereum/android/db/BlockStoreDatabase.java new file mode 100644 index 00000000..f9b3ed59 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/db/BlockStoreDatabase.java @@ -0,0 +1,34 @@ +package org.ethereum.android.db; + +import org.ethereum.core.Block; +import org.ethereum.core.TransactionReceipt; + +import java.math.BigInteger; +import java.util.List; + +public interface BlockStoreDatabase { + + public List getByNumber(Long number); + + public List getByHash(byte[] hash); + + public List getHashListByNumberLimit(Long from, Long to); + + public void deleteBlocksSince(long number); + + public void save(BlockVO block); + + public BigInteger getTotalDifficultySince(long number); + + public BigInteger getTotalDifficulty(); + + public Block getBestBlock(); + + public List getAllBlocks(); + + public void reset(); + + public void save(TransactionReceiptVO transactionReceiptVO); + + public TransactionReceipt getTransactionReceiptByHash(byte[] hash); +} diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/db/BlockStoreImpl.java b/ethereumj-core-android/src/main/java/org/ethereum/android/db/BlockStoreImpl.java index 997ff208..bed633c9 100644 --- a/ethereumj-core-android/src/main/java/org/ethereum/android/db/BlockStoreImpl.java +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/db/BlockStoreImpl.java @@ -6,17 +6,16 @@ import org.ethereum.db.BlockStore; import org.ethereum.util.ByteUtil; import java.math.BigInteger; +import java.util.ArrayList; import java.util.List; public class BlockStoreImpl implements BlockStore { - private BlockDatabaseHelper blockDao; - private TransactionDatabaseHelper transactionDao; + private BlockStoreDatabase database; - public BlockStoreImpl(BlockDatabaseHelper blockDao, TransactionDatabaseHelper transactionDao) { + public BlockStoreImpl(BlockStoreDatabase database) { - this.blockDao = blockDao; - this.transactionDao = transactionDao; + this.database = database; } public byte[] getBlockHashByNumber(long blockNumber) { @@ -29,65 +28,86 @@ public class BlockStoreImpl implements BlockStore { public Block getBlockByNumber(long blockNumber) { - /* - List result = sessionFactory.getCurrentSession(). - createQuery("from BlockVO where number = :number"). - setParameter("number", blockNumber).list(); + + List result = database.getByNumber(blockNumber); + if (result.size() == 0) return null; + BlockVO vo = (BlockVO) result.get(0); + + return new Block(vo.rlp); + } + + public Block getBlockByHash(byte[] hash) { + + List result = database.getByHash(hash); if (result.size() == 0) return null; BlockVO vo = (BlockVO) result.get(0); return new Block(vo.rlp); - */ - return null; } - public Block getBlockByHash(byte[] hash) { - - return null; - } - - @SuppressWarnings("unchecked") public List getListOfHashesStartFrom(byte[] hash, int qty) { - return null; + List hashes = new ArrayList(); + + // find block number of that block hash + Block block = getBlockByHash(hash); + if (block == null) return hashes; + + hashes = database.getHashListByNumberLimit(block.getNumber(), block.getNumber() - qty); + + return hashes; } public void deleteBlocksSince(long number) { + database.deleteBlocksSince(number); } public void saveBlock(Block block, List receipts) { + BlockVO blockVO = new BlockVO(block.getNumber(), block.getHash(), + block.getEncoded(), block.getCumulativeDifficulty()); + + for (TransactionReceipt receipt : receipts) { + + byte[] hash = receipt.getTransaction().getHash(); + byte[] rlp = receipt.getEncoded(); + + TransactionReceiptVO transactionReceiptVO = new TransactionReceiptVO(hash, rlp); + database.save(transactionReceiptVO); + } + + database.save(blockVO); } public BigInteger getTotalDifficultySince(long number) { - return null; + return database.getTotalDifficultySince(number); } public BigInteger getTotalDifficulty() { - return null; + return database.getTotalDifficulty(); } public Block getBestBlock() { - return null; + return database.getBestBlock(); } - @SuppressWarnings("unchecked") public List getAllBlocks() { - return null; + return database.getAllBlocks(); } public void reset() { + database.reset(); } public TransactionReceipt getTransactionReceiptByHash(byte[] hash) { - return null; + return database.getTransactionReceiptByHash(hash); } } diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/db/BlockVO.java b/ethereumj-core-android/src/main/java/org/ethereum/android/db/BlockVO.java new file mode 100644 index 00000000..6d5fba17 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/db/BlockVO.java @@ -0,0 +1,66 @@ +package org.ethereum.android.db; + +import com.j256.ormlite.field.DataType; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + +import java.math.BigInteger; + +@DatabaseTable(tableName = "block") +public class BlockVO { + + @DatabaseField(index = true, dataType = DataType.BYTE_ARRAY) + byte[] hash; + + @DatabaseField(index = true, dataType = DataType.LONG_OBJ) + Long number; + + @DatabaseField(columnName = "cumulativedifficulty", dataType = DataType.BIG_INTEGER) + BigInteger cumulativeDifficulty; + + @DatabaseField(dataType = DataType.BYTE_ARRAY) + byte[] rlp; + + public BlockVO() { + } + + public BlockVO(Long number, byte[] hash, byte[] rlp, BigInteger cumulativeDifficulty) { + this.number = number; + this.hash = hash; + this.rlp = rlp; + this.cumulativeDifficulty = cumulativeDifficulty; + } + + public byte[] getHash() { + return hash; + } + + public void setHash(byte[] hash) { + this.hash = hash; + } + + public Long getIndex() { + return number; + } + + public void setIndex(Long number) { + this.number = number; + } + + public byte[] getRlp() { + return rlp; + } + + public void setRlp(byte[] rlp) { + this.rlp = rlp; + } + + public BigInteger getCumulativeDifficulty() { + return cumulativeDifficulty; + } + + public void setCumulativeDifficulty(BigInteger cumulativeDifficulty) { + this.cumulativeDifficulty = cumulativeDifficulty; + } + +} diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/db/OrmLiteBlockStoreDatabase.java b/ethereumj-core-android/src/main/java/org/ethereum/android/db/OrmLiteBlockStoreDatabase.java new file mode 100644 index 00000000..7c8ef683 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/db/OrmLiteBlockStoreDatabase.java @@ -0,0 +1,255 @@ +package org.ethereum.android.db; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.util.Log; + +import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper; +import com.j256.ormlite.dao.Dao; +import com.j256.ormlite.dao.GenericRawResults; +import com.j256.ormlite.stmt.DeleteBuilder; +import com.j256.ormlite.support.ConnectionSource; +import com.j256.ormlite.table.TableUtils; + +import org.ethereum.core.Block; +import org.ethereum.core.TransactionReceipt; + +import java.math.BigInteger; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class OrmLiteBlockStoreDatabase extends OrmLiteSqliteOpenHelper implements BlockStoreDatabase { + + private static final String DATABASE_NAME = "blockchain.db"; + private static final int DATABASE_VERSION = 1; + + private Dao blockDao = null; + private Dao transactionDao = null; + + public OrmLiteBlockStoreDatabase(Context context) { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + + /** + * This is called when the database is first created. Usually you should call createTable statements here to create + * the tables that will store your data. + */ + @Override + public void onCreate(SQLiteDatabase db, ConnectionSource connectionSource) { + + try { + Log.i(OrmLiteBlockStoreDatabase.class.getName(), "onCreate"); + TableUtils.createTable(connectionSource, BlockVO.class); + TableUtils.createTable(connectionSource, TransactionReceiptVO.class); + } catch (SQLException e) { + Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Can't create database", e); + throw new RuntimeException(e); + } + } + + /** + * This is called when your application is upgraded and it has a higher version number. This allows you to adjust + * the various data to match the new version number. + */ + @Override + public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion) { + + try { + Log.i(OrmLiteBlockStoreDatabase.class.getName(), "onUpgrade"); + TableUtils.dropTable(connectionSource, BlockVO.class, true); + TableUtils.dropTable(connectionSource, TransactionReceiptVO.class, true); + // after we drop the old databases, we create the new ones + onCreate(db, connectionSource); + } catch (SQLException e) { + Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Can't drop databases", e); + throw new RuntimeException(e); + } + } + + /** + * Returns the Database Access Object (DAO) for our SimpleData class. It will create it or just give the cached + * value. + */ + public Dao getBlockDao() throws SQLException { + + if (blockDao == null) { + blockDao = getDao(BlockVO.class); + } + return blockDao; + } + + /** + * Returns the Database Access Object (DAO) for our SimpleData class. It will create it or just give the cached + * value. + */ + public Dao getTransactionDao() throws SQLException { + if (transactionDao == null) { + transactionDao = getDao(TransactionReceiptVO.class); + } + return transactionDao; + } + + /** + * Close the database connections and clear any cached DAOs. + */ + @Override + public void close() { + + super.close(); + blockDao = null; + transactionDao = null; + } + + public List getByNumber(Long number) { + + List list = new ArrayList(); + try { + list = getBlockDao().queryForEq("number", number); + } catch(java.sql.SQLException e) { + Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error querying for number", e); + } + + return list; + } + + public List getByHash(byte[] hash) { + + List list = new ArrayList(); + try { + list = getBlockDao().queryForEq("hash", hash); + } catch(java.sql.SQLException e) { + Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error querying for hash", e); + } + + return list; + } + + public List getHashListByNumberLimit(Long from, Long to) { + + List results = new ArrayList(); + try { + List list = new ArrayList(); + list = getBlockDao().queryBuilder().orderBy("number", false).limit(to - from).where().between("number", from, to).query(); + for (BlockVO block : list) { + results.add(block.hash); + } + } catch(java.sql.SQLException e) { + Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error querying for hash list", e); + } + + return results; + } + + public void deleteBlocksSince(long number) { + + try { + DeleteBuilder deleteBuilder = getBlockDao().deleteBuilder(); + deleteBuilder.where().gt("number", number); + deleteBuilder.delete(); + } catch(java.sql.SQLException e) { + Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error deleting blocks since", e); + } + } + + public void save(BlockVO block) { + + try { + getBlockDao().create(block); + } catch(java.sql.SQLException e) { + Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error saving block", e); + } + } + + public BigInteger getTotalDifficultySince(long number) { + + try { + GenericRawResults rawResults = getBlockDao().queryRaw("select sum(cumulativedifficulty) from block where number > " + number); + List results = rawResults.getResults(); + return new BigInteger(results.get(0)[0]); + } catch(java.sql.SQLException e) { + Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error getting total difficulty since", e); + } + return null; + } + + public BigInteger getTotalDifficulty() { + + try { + GenericRawResults rawResults = getBlockDao().queryRaw("select sum(cumulativedifficulty) from block"); + List results = rawResults.getResults(); + return new BigInteger(results.get(0)[0]); + } catch(java.sql.SQLException e) { + Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error getting total difficulty", e); + } + return null; + } + + public Block getBestBlock() { + + Long bestNumber = null; + try { + GenericRawResults rawResults = getBlockDao().queryRaw("select max(number) from block"); + List results = rawResults.getResults(); + if (results.size() > 0 && results.get(0).length > 0) { + bestNumber = Long.valueOf(results.get(0)[0]); + } + } catch(java.sql.SQLException e) { + Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Sql Error getting best block", e); + } catch (Exception e) { + Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error getting best block", e); + } + + if (bestNumber == null) return null; + List result = getByNumber(bestNumber); + + if (result.isEmpty()) return null; + BlockVO vo = (BlockVO) result.get(0); + + return new Block(vo.rlp); + } + + public List getAllBlocks() { + + ArrayList blocks = new ArrayList<>(); + try { + for (BlockVO blockVO : getBlockDao()) { + blocks.add(new Block(blockVO.getRlp())); + } + } catch(java.sql.SQLException e) { + Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error getting all blocks", e); + } + + return blocks; + } + + public void reset() { + + deleteBlocksSince(Long.valueOf(0)); + } + + public void save(TransactionReceiptVO transactionReceiptVO) { + + try { + getTransactionDao().create(transactionReceiptVO); + } catch(java.sql.SQLException e) { + Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error saving transaction", e); + } + } + + public TransactionReceipt getTransactionReceiptByHash(byte[] hash) { + + List list = new ArrayList(); + try { + list = getTransactionDao().queryForEq("hash", hash); + } catch(java.sql.SQLException e) { + Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error querying for hash", e); + } + + if (list.size() == 0) return null; + TransactionReceiptVO vo = list.get(0); + + return new TransactionReceipt(vo.rlp); + + } +} diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/db/TransactionDatabaseHelper.java b/ethereumj-core-android/src/main/java/org/ethereum/android/db/TransactionDatabaseHelper.java deleted file mode 100644 index ae68de70..00000000 --- a/ethereumj-core-android/src/main/java/org/ethereum/android/db/TransactionDatabaseHelper.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.ethereum.android.db; - - -import java.sql.SQLException; - -import android.content.Context; -import android.database.sqlite.SQLiteDatabase; -import android.util.Log; - -import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper; -import com.j256.ormlite.dao.Dao; -import com.j256.ormlite.support.ConnectionSource; -import com.j256.ormlite.table.TableUtils; - -import org.ethereum.db.TransactionReceiptVO; - -/** - * Database helper class used to manage the creation and upgrading of your database. This class also usually provides - * the DAOs used by the other classes. - */ -public class TransactionDatabaseHelper extends OrmLiteSqliteOpenHelper { - - private static final String DATABASE_NAME = "transactions.db"; - private static final int DATABASE_VERSION = 1; - - // the DAO object we use to access the SimpleData table - private Dao dao = null; - - public TransactionDatabaseHelper(Context context) { - super(context, DATABASE_NAME, null, DATABASE_VERSION); - } - - /** - * This is called when the database is first created. Usually you should call createTable statements here to create - * the tables that will store your data. - */ - @Override - public void onCreate(SQLiteDatabase db, ConnectionSource connectionSource) { - try { - Log.i(BlockDatabaseHelper.class.getName(), "onCreate"); - TableUtils.createTable(connectionSource, TransactionReceiptVO.class); - } catch (SQLException e) { - Log.e(BlockDatabaseHelper.class.getName(), "Can't create database", e); - throw new RuntimeException(e); - } - } - - /** - * This is called when your application is upgraded and it has a higher version number. This allows you to adjust - * the various data to match the new version number. - */ - @Override - public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion) { - try { - Log.i(BlockDatabaseHelper.class.getName(), "onUpgrade"); - TableUtils.dropTable(connectionSource, TransactionReceiptVO.class, true); - // after we drop the old databases, we create the new ones - onCreate(db, connectionSource); - } catch (SQLException e) { - Log.e(BlockDatabaseHelper.class.getName(), "Can't drop databases", e); - throw new RuntimeException(e); - } - } - - /** - * Returns the Database Access Object (DAO) for our SimpleData class. It will create it or just give the cached - * value. - */ - public Dao getBlockDao() throws SQLException { - if (dao == null) { - dao = getDao(TransactionReceiptVO.class); - } - return dao; - } - - /** - * Close the database connections and clear any cached DAOs. - */ - @Override - public void close() { - super.close(); - dao = null; - } -} diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/db/TransactionReceiptVO.java b/ethereumj-core-android/src/main/java/org/ethereum/android/db/TransactionReceiptVO.java new file mode 100644 index 00000000..341fbb1c --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/db/TransactionReceiptVO.java @@ -0,0 +1,49 @@ +package org.ethereum.android.db; + +import com.j256.ormlite.field.DataType; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Lob; +import javax.persistence.Table; + +/** + * @author Roman Mandeleil + * @since 14.11.2014 + */ +@DatabaseTable(tableName = "transaction_receipt") +public class TransactionReceiptVO { + + @DatabaseField(index = true, dataType = DataType.BYTE_ARRAY) + byte[] hash; + + @DatabaseField(dataType = DataType.BYTE_ARRAY) + byte[] rlp; + + public TransactionReceiptVO() { + } + + public TransactionReceiptVO(byte[] hash, byte[] rlp) { + this.hash = hash; + this.rlp = rlp; + } + + public byte[] getHash() { + return hash; + } + + public void setHash(byte[] hash) { + this.hash = hash; + } + + public byte[] getRlp() { + return rlp; + } + + public void setRlp(byte[] rlp) { + this.rlp = rlp; + } + +} diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/di/modules/EthereumModule.java b/ethereumj-core-android/src/main/java/org/ethereum/android/di/modules/EthereumModule.java index 793f0abd..c5818731 100644 --- a/ethereumj-core-android/src/main/java/org/ethereum/android/di/modules/EthereumModule.java +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/di/modules/EthereumModule.java @@ -2,12 +2,15 @@ package org.ethereum.android.di.modules; import android.content.Context; +import com.j256.ormlite.android.apptools.OpenHelperManager; + import org.ethereum.android.datasource.LevelDbDataSource; +import org.ethereum.android.db.OrmLiteBlockStoreDatabase; +import org.ethereum.android.db.BlockStoreImpl; import org.ethereum.config.SystemProperties; import org.ethereum.core.BlockchainImpl; import org.ethereum.core.Wallet; import org.ethereum.db.BlockStore; -import org.ethereum.db.InMemoryBlockStore; import org.ethereum.db.RepositoryImpl; import org.ethereum.facade.Blockchain; import org.ethereum.facade.Ethereum; @@ -72,7 +75,8 @@ public class EthereumModule { @Provides @Singleton BlockStore provideBlockStore() { - return new InMemoryBlockStore(); + OrmLiteBlockStoreDatabase database = OpenHelperManager.getHelper(context, OrmLiteBlockStoreDatabase.class); + return new BlockStoreImpl(database); } @Provides diff --git a/ethereumj-core/build.gradle b/ethereumj-core/build.gradle index d95af860..b27b2eaf 100644 --- a/ethereumj-core/build.gradle +++ b/ethereumj-core/build.gradle @@ -100,7 +100,7 @@ test { logger.lifecycle("Running test: ${descriptor}") } - jvmArgs '-Xss32m' + jvmArgs += [ "-Xss32m", "-XX:MaxPermSize=256m" ] testLogging { events "failed" diff --git a/gradle.properties b/gradle.properties index 1d3591c8..a31c0f9d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,4 +15,6 @@ # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true \ No newline at end of file +# org.gradle.parallel=true + +org.gradle.jvmargs=-XX:MaxPermSize=512m \ No newline at end of file