no datasource configured

366 views
Skip to first unread message

hmpf

unread,
Feb 19, 2012, 2:16:59 AM2/19/12
to Empire
Hi,

Thanks for providing this awesome lib!
Well, I'm still having trouble setting it up, as play tells me "no
datasource configured", when I start my application.
Basically it works, if I run the whole thing in batch (in a static
main method), but it doesn't work when I launch the server.
It seems logical, they state that if you annotate anything with
"@javax.persistence.Entity", play expects a properly configured JDBC
datasource. I don't know how to do this for Empire in the
application.conf file, so I don't configure anything here. Instead, I
created a Bootstrap class using @OnApplicationStart tag like this:

@OnApplicationStart
public class Bootstrap extends Job {

public void doJob() throws Exception {
Logger.info("init");
Empire.init(new OpenRdfEmpireModule());
PersistenceProvider aProvider = Empire.get().persistenceProvider();
EntityManager aManager = aProvider.createEntityManagerFactory("",
new HashMap()).createEntityManager();
Logger.info("init done");
}
}

But I get the following error:

@69e524djn
Internal Server Error (500) for request GET /

JPA error
A JPA error occurred (Cannot start a JPA manager without a properly
configured database): No datasource configured

play.exceptions.JPAException: Cannot start a JPA manager without a
properly configured database
at play.db.jpa.JPAPlugin.onApplicationStart(JPAPlugin.java:115)
at
play.plugins.PluginCollection.onApplicationStart(PluginCollection.java:
480)
at play.Play.start(Play.java:515)
at play.Play.detectChanges(Play.java:618)
at play.Invoker$Invocation.init(Invoker.java:198)
at Invocation.HTTP Request(Play!)
Caused by: java.lang.NullPointerException: No datasource configured
... 6 more


This is, because play finds @Entity-annotated classes and no JDBC
backend is configured. If I do configure "db=mem", the error message
is different. Play gives me a hybernate-connection and expects ID
members in every @Entity-annotated class.

What is the right way to setup a play app using Empire as its only
datasource?
Btw, I think, it would be very helpful to have a simple but complete
example app in the distribution.

Thanks in advance,
Daniel

Mike Grove

unread,
Feb 19, 2012, 2:06:54 PM2/19/12
to empir...@googlegroups.com
Are you using Imperium [1] and if so, with what version of Play!

The stacktrace you provided shows that Play is complaining about a
lack of a database, so I'd guess is something in your Play! config.
It will require *some* database, even if its a dummy db that you're
not going to use, but afaik, Play! won't function without one. You
might be able to remove their JPA plugin and just use Imperium, but
that's not something I've tried.

Many of the Play internals were quite JPA/SQL specific in the 1.1 and
earlier releases. I am not familiar w/ 1.2 or the forthcoming 2.0,
but I doubt that has changed. I mentioned this tight dependency to
Guillame on their list and that it made it hard to swap in something
like Empire, but I don't know if any efforts were made on that front
to remedy the issue.

Cheers,

Mike


[1] https://github.com/mhgrove/Imperium

hmpf

unread,
Feb 20, 2012, 9:34:35 AM2/20/12
to Empire
Thanks for your timely response!
That changed a few things... well, it's still not working :D

This is what I did:

* build latest version of Imperium

* copy the libs from dist directory into my newly created play! app's
lib folder
- excluding play, javassist and jpa libs (I assume, they are already
part of play)

* made entry for Empire Plugin in conf/play.plugins:

1001:com.clarkparsia.play.imperium.EmpirePlugin

* created /empire.configuration:

annotation.provider =
com.clarkparsia.empire.util.PropertiesAnnotationProvider
0.name = demo
0.factory =
com.clarkparsia.empire.sesametwo.RepositoryDataSourceFactory
0.url = http://localhost:8090/openrdf-sesame
0.repo = temp

1.name = context2
1.factory = com.clarkparsia.empire.jena.JenaTestDataSourceFactory

* created /empire.annotation.index

com.clarkparsia.empire.annotation.RdfsClass=models.Term
javax.persistence.NamedQuery=

* the ...NamedQuery property is empty, because I don't know what to
specify here

* enabled db=mem in application.conf (the only thing I changed)

* created a Model class

package models;
import ...
@Namespaces({
"dc", "http://purl.org/dc/elements/1.1/",
...
})
@RdfsClass("zbwext:Descriptor")
@Entity
public class Term extends RdfModel {

@RdfProperty("skos:prefLabel")
private String prefLabel;

public String getPrefLabel() {
return prefLabel;
}

public void setPrefLabel(String prefLabel) {
this.prefLabel = prefLabel;
}
}

* and created a simple init test in my controller

public static void index() {
Empire.init(new OpenRdfEmpireModule());

// create an EntityManager for the specified persistence context
EntityManager aManager =
Persistence.createEntityManagerFactory("demo")
.createEntityManager();

Term term = Imperium.em().find(Term.class, URI.create("http://zbw.eu/
stw/descriptor/11182-6"));

System.out.println("Term: "+ term.getRdfId());
render();
}

That's all I've done. And here is the output when I run play:

Listening for transport dt_socket at address: 8000
14:29:21,202 INFO ~ Starting C:\data\workspace-play\imperial3
14:29:21,827 WARN ~ You're running Play! in DEV mode
14:29:21,913 INFO ~ Listening for HTTP on port 9000 (Waiting a first
request to start) ...
14:29:29,188 INFO ~ Connected to jdbc:hsqldb:mem:playembed
14:29:29,991 INFO ~ Application 'imperial3' is now started !
com.google.inject.ProvisionException: Guice provision errors:

1) Error injecting com.clarkparsia.play.imperium.Imperium using
com.clarkparsia.empire.spi.guice.PersistenceContextInjector@640f078c.
Reason: java.lang.RuntimeException: Factory incorrectly initialized,
or a factory provided that does not exists was specified. Cannot
create EntityManager
while locating com.clarkparsia.play.imperium.Imperium

1 error
at com.google.inject.internal.InjectorImpl$4.get(InjectorImpl.java:
987)
at
com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:
1013)
at com.clarkparsia.empire.Empire.instance(Unknown Source)
at com.clarkparsia.play.imperium.Imperium.create(Imperium.java:84)
at com.clarkparsia.play.imperium.Imperium.get(Imperium.java:59)
at com.clarkparsia.play.imperium.Imperium.em(Imperium.java:70)
at
com.clarkparsia.play.imperium.EmpirePlugin.startTx(EmpirePlugin.java:
218)
at
com.clarkparsia.play.imperium.EmpirePlugin.beforeInvocation(EmpirePlugin.java:
177)
at play.Invoker$Invocation.before(Invoker.java:114)
at play.Invoker$Invocation.run(Invoker.java:175)
at play.server.HttpHandler$MinaInvocation.run(HttpHandler.java:488)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown
Source)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor
$ScheduledFutureTask.access$201(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor
$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.RuntimeException: Factory incorrectly
initialized, or a factory provided that does not exists was
specified. Cannot create EntityManager
at
com.clarkparsia.empire.spi.guice.PersistenceContextInjector.injectMembers(Unknown
Source)
at
com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:
120)
at
com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:
94)
at com.google.inject.internal.ConstructorBindingImpl
$Factory.get(ConstructorBindingImpl.java:254)
at com.google.inject.internal.InjectorImpl$4$1.call(InjectorImpl.java:
978)
at
com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:
1024)
at com.google.inject.internal.InjectorImpl$4.get(InjectorImpl.java:
974)
... 18 more
14:29:30,529 ERROR ~


I looked into the Imperium sources. The problem occurs here:

private static Imperium create() {
if (mLocalInst.get() != null) {
mLocalInst.get().getEntityManager().close();

mLocalInst.remove();
}

---> Imperium aEmpire = Empire.get().instance(Imperium.class);

mLocalInst.set(aEmpire);

return aEmpire;
}


Can you see what might be the problem?
It would be awesome to have an executable example. As soon as it runs
properly on my place, I'll make one and submit if you like.

Cheers and thanks in advance,
Daniel

Mike Grove

unread,
Feb 20, 2012, 9:57:22 AM2/20/12
to empir...@googlegroups.com
On Mon, Feb 20, 2012 at 9:34 AM, hmpf <dnl...@gmail.com> wrote:
> Thanks for your timely response!
> That changed a few things... well, it's still not working :D
>
> This is what I did:
>
>  * build latest version of Imperium
>

I will point out that I've never tested Imperium w/ Play 1.1 or newer.
You didn't specify which version of Play! you're using, but if its
recent, it's possible that something in the Play! startup has changed
such that the Imperium startup won't work anymore.

>  * copy the libs from dist directory into my newly created play! app's
> lib folder
>        - excluding play, javassist and jpa libs (I assume, they are already
> part of play)
>

Play & JPA do. Javassist you might want to double check. iirc, Play!
does use Javassist, but the versions might not be the same. I don't
think that would contribute to the issue you're seeing, but it's worth
mentioning.

>  * made entry for Empire Plugin in conf/play.plugins:
>
> 1001:com.clarkparsia.play.imperium.EmpirePlugin
>
>  * created /empire.configuration:
>
> annotation.provider =
> com.clarkparsia.empire.util.PropertiesAnnotationProvider
> 0.name = demo
> 0.factory =
> com.clarkparsia.empire.sesametwo.RepositoryDataSourceFactory
> 0.url = http://localhost:8090/openrdf-sesame
> 0.repo = temp
>
> 1.name = context2
> 1.factory = com.clarkparsia.empire.jena.JenaTestDataSourceFactory
>

These look fine, but I suggest using the aliases "sesame" and "jena"
respectively for the factories.

>  * created /empire.annotation.index
>
> com.clarkparsia.empire.annotation.RdfsClass=models.Term
> javax.persistence.NamedQuery=
>
>  * the ...NamedQuery property is empty, because I don't know what to
> specify here

That's ok. These just specify which classes contain the specified
annotations. It can be expensive to scan the entire classpath to find
these things, so this helps alleviate that by just telling Empire
where to look.

>
>  * enabled  db=mem  in application.conf  (the only thing I changed)
>
>  * created a Model class
>
> package models;
> import ...
> @Namespaces({
>        "dc",   "http://purl.org/dc/elements/1.1/",
>        ...
> })
> @RdfsClass("zbwext:Descriptor")
> @Entity
> public class Term extends RdfModel {
>
>        @RdfProperty("skos:prefLabel")
>        private String prefLabel;
>
>        public String getPrefLabel() {
>                return prefLabel;
>        }
>
>        public void setPrefLabel(String prefLabel) {
>                this.prefLabel = prefLabel;
>        }
> }
>
>  * and created a simple init test in my controller
>
> public static void index() {
>        Empire.init(new OpenRdfEmpireModule());

Don't include this call to init. You should let Imperium worry about
initializing Empire.

>
>        // create an EntityManager for the specified persistence context
>        EntityManager aManager =
> Persistence.createEntityManagerFactory("demo")
>                                                                                .createEntityManager();

This is not the correct way to get an EntityManager w/ Imperium...

>
>        Term term = Imperium.em().find(Term.class, URI.create("http://zbw.eu/
> stw/descriptor/11182-6"));

... however this is.

Imperium auto-starts transactions like the JPA plugin, this part of
the trace is in that code intercepting the call before it gets to your
controller. From the error message, it sounds like Empire could not
find its configuration file. You might want to double check the
location of the file, perhaps put a breakpoint into Empire and see if
its correctly reading in the configuration. Easiest thing here would
be to put a breakpoint in the constructor of DefaultEmpireModule which
is where it will load the configuration and see if its completed
correctly.

Yes, a minimal running example would be a great resource to have.

Cheers,

Mike

hmpf

unread,
Feb 21, 2012, 3:55:07 AM2/21/12
to Empire
Sorry, I wasn't clear on the versions I'm using. I tried using the
latest versions, but to make sure this is not the root of the problem,
I switched to the following versions:
* play-1.0.3.2
* latest imperium distribution (0.2) and its libraries
* I did not include any other libraries

But the problem did not change.

So I started debugging the whole thing, I removed empire-core.jar from
the classpath and included the sources directly, so I can work with
them.
As you said, apparently the DefaultEmpireModule constructor is *never*
executed, so it doesn't try to read the config files at all (?),
however, there are some DefaultEmpireModule instances, probably
injected.
I checked the Empire class: The constructor is not invoked in the
following method, because injector is not null:

private static Injector injector() {
if (injector == null) {
injector = Guice.createInjector(new DefaultEmpireModule());
}
return injector;
}

and neither during the init() method, because aModules is not empty:

public static void init(Collection<EmpireModule> theModules) {
mModules.clear();

Collection<EmpireModule> aModules = new
HashSet<EmpireModule>(theModules);

if (aModules.isEmpty() || !find2(aModules, new
FindDefaultEmpireModulePredicate())) {
aModules.add(new DefaultEmpireModule());
}

// keep track of the modules we've "installed"
for (Module aModule : aModules) {
mModules.put(aModule.getClass(), aModule);
}

injector = Guice.createInjector(mModules.values());
}

There are two entries in var theModules:
* DefaultEmpireModule with members:
- mAnnotationProvider: class
com.clarkparsia.empire.util.PropertiesAnnotationProvider
- but all entries are null but the name property
- mGeneralConfiguration without any entries
- mUnitConfiguration with one String entry: "imperium"
* com.clarkparsia.empire.sesametwo.OpenRdfEmpireModule
- which I did not explore any further


I'm totally blur at the moment :D
Any ideas?

Thanks again,
Daniel

Mike Grove

unread,
Feb 21, 2012, 8:00:43 AM2/21/12
to empir...@googlegroups.com

Well if theModules contains an instance of DefaultEmpireModule, a
constructor is being called. It sounds like its the case that it
could not find an empire configuration file in any standard location
and tried to cobble one together from what was in your application
conf or read a VirtualFile out of the conf directory.

If you put a breakpoint in the EmpirePlugin, you can see @ L102 where
it tries to build a configuration based on what's in Play!'s
configuration. Looking at the isEmpireConfigFound method in
EmpirePlugin, it's out of date wrt to what Empire would prefer. In
fact, looking at your previous email, I see you said you created a
file 'empire.configuration' which is correct, but Imperium does not
check for that file as it was written against an earlier version of
Empire.

The workaround would appear to be seeing in your application.conf the
property "empire.config" to the file path to your configuration file.
If that resolves the problem, I'll update the EmpirePlugin to reflect
the current status of Empire.

Cheers,

Mike

hmpf

unread,
Feb 21, 2012, 11:23:22 AM2/21/12
to Empire
Yeah, it's running!

There were two different issues though:

1. As you said, it didn't find the empire.configuration file. Making
an entry in application.conf didn't help, but renaming it to
empire.config did the job.

2. After spending some time debugging, I found that it looks for a
factory named "imperium" for which nothing was configured. I renamed
mine from "demo" to "imperium", and suddenly it worked

Thanks a lot for your support!
I'm setting up a demo application, so other users can learn by
example...

Cheers,
Daniel :)
Reply all
Reply to author
Forward
0 new messages