Play Framework 2.1(Java)eBean @Encrypted Annotation Errors
I'm trying to use the ebean @ encrypted annotation on the string field for the database model The document makes it look simple, but I got a very vague runtime error using the built-in H2 memory database in the browser:
package models; import java.util.*; import javax.persistence.*; import play.db.ebean.*; import play.db.ebean.Model.Finder; import play.data.format.*; import play.data.validation.*; import com.avaje.ebean.*; import com.avaje.ebean.annotation.*; @Entity public class Test extends Model { @Id public Long id; @Encrypted public String identifier; }
The following runtime errors related to the @ encrypted annotation were generated:
Unexpected exception RuntimeException: Error reading annotations for models.Test No source available,here is the exception stack trace: ->java.lang.RuntimeException: Error reading annotations for models.Test com.avaje.ebeaninternal.server.deploy.parse.ReadAnnotations.readInitial(ReadAnnotations.java:26) com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.createDeployBeanInfo(BeanDescriptorManager.java:1026) com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.readEntityDeploymentInitial(BeanDescriptorManager.java:533) com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.deploy(BeanDescriptorManager.java:250) com.avaje.ebeaninternal.server.core.InternalConfiguration.<init>(InternalConfiguration.java:124) com.avaje.ebeaninternal.server.core.DefaultServerFactory.createServer(DefaultServerFactory.java:210) com.avaje.ebeaninternal.server.core.DefaultServerFactory.createServer(DefaultServerFactory.java:64) com.avaje.ebean.EbeanServerFactory.create(EbeanServerFactory.java:59) play.db.ebean.EbeanPlugin.onStart(EbeanPlugin.java:79) play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:63) play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:63) scala.collection.immutable.List.foreach(List.scala:309) play.api.Play$$anonfun$start$1.apply$mcV$sp(Play.scala:63) play.api.Play$$anonfun$start$1.apply(Play.scala:63) play.api.Play$$anonfun$start$1.apply(Play.scala:63) play.utils.Threads$.withContextClassLoader(Threads.scala:18) play.api.Play$.start(Play.scala:62) play.core.ReloadableApplication$$anonfun$get$1$$anonfun$1.apply(ApplicationProvider.scala:133) play.core.ReloadableApplication$$anonfun$get$1$$anonfun$1.apply(ApplicationProvider.scala:106) scala.Option.map(Option.scala:145) play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:106) play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:104) scala.util.Either$RightProjection.flatMap(Either.scala:523) play.core.ReloadableApplication.get(ApplicationProvider.scala:104) play.core.server.Server$class.sendHandler$1(Server.scala:56) play.core.server.Server$$anonfun$getHandlerFor$4.apply(Server.scala:88) play.core.server.Server$$anonfun$getHandlerFor$4.apply(Server.scala:87) scala.util.Either$RightProjection.flatMap(Either.scala:523) play.core.server.Server$class.getHandlerFor(Server.scala:87) play.core.server.NettyServer.getHandlerFor(NettyServer.scala:34) play.core.server.netty.PlayDefaultUpstreamHandler.messageReceived(PlayDefaultUpstreamHandler.scala:103) org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:75) org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:565) org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:793) org.jboss.netty.handler.codec.http.HttpContentDecoder.messageReceived(HttpContentDecoder.java:104) org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:75) org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:565) org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:793) org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296) org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:455) org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:538) org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:437) org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:75) org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:565) org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:560) org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268) org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255) org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:84) org.jboss.netty.channel.socket.nio.AbstractNioWorker.processSelectedKeys(AbstractNioWorker.java:472) org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:333) org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:35) org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:102) org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) java.lang.Thread.run(Thread.java:722)
I have correctly configured the encryptionkeymanager setting in the configuration (ebean. Encryptkeymanager = "com. Avaje. Tests. Basic. Encrypt. Basicencyptkeymanager") Everything was fine without any problems or even warnings
I even tried to manually add ebean 2.7.0 to the project 1 as a dependency does not help
Know what this means and why I received this error?
Solution
I believe I may have solved the problem, but in a very circuitous way The problem is that the play framework cannot resolve the basicencryptkeymanager class in the ebean package I found this when looking at the complete stack trace, because I saw the message "no encryptkeymanager defined", even if I explicitly specified it in the settings file (application.conf, ebean.conf, ebean.properties - your name, it, I tried it) according to the official documentation
Therefore, I had to use serverconfigstartup to create my own from scratch (note that this is only a fast and dirty example and may not be the safest or most effective method):
package models; import com.avaje.ebean.config.ServerConfig; import com.avaje.ebean.event.ServerConfigStartup; import com.avaje.ebean.config.EncryptKey; import com.avaje.ebean.config.EncryptKeyManager; public class CustomServerConfigStartup implements ServerConfigStartup { @Override public void onStart(ServerConfig serverConfig) { serverConfig.setEncryptKeyManager(new BasicEncryptKeyManager()); } } class BasicEncryptKeyManager implements EncryptKeyManager{ @Override public EncryptKey getEncryptKey(String tableName,String columnName) { return new CustomEncryptKey(tableName,columnName); } @Override public void initialise() { //Do nothing (yet) } } class CustomEncryptKey implements EncryptKey{ private String tableName; private String columnName; public CustomEncryptKey(String tableName,String columnName){ this.tableName = tableName; this.columnName = columnName; } @Override public String getStringValue() { return play.Configuration.root().getString("application.secret") + "::" + this.tableName + "::" + this.columnName; } }
Then, in the conf directory of the play application, click application Conf or ebean In the properties file (this step may be redundant):
ebean.encryptKeyManager="models.BasicEncryptKeyManager"
This seems to solve the @ encrypted annotation error It seems that play must include an accessible encryptionkeymanager class in a future version of the ebean actual framework to avoid this solution