WSO2 - Configuring JPA - jpa

We developed an app using JPA (via Hibernate).
And in WSO2 we expose a service in soap that uses the models defined in our app.
The persistence is configured through a persistence.xml file.
The way we deployed it is :
.car contains .aar (our app that contains a jar with our models)
inside the .jar in META-INF I can see the persistence file, but when calling the service it complaines about the fact that it can't find the persistence.
I tried to put the persistence file at the .aar level too but no success.
Do I need to put the persistence file at a particular place ?
Thanks !

Related

Packaging JPA entities in a jar inside a Spring Boot application

I am refactoring a JEE REST (using JAX-RS 2.0) application as a Spring Boot application. My old app is packaged in a .war and has a jar file with entities and the persistence.xml configuration file for JPA. This jar is copied into WEB-INF/lib directory. I know Spring JPA works a different way and I don't use persistence.xml now but I wonder if I can package my JPA entity classes in a jar and include them in my Spring Boot apps just like I am doing now. This way I can easily reuse that jar in different Spring Boot Applications.
I'm pretty certain you can do this since I have done the same on one of my projects very recently. The only thing you need to do is make sure that you add an #EntityScan annotation on your main Spring Boot config class with the base package of your entities in the JAR.
#EntityScan("my.external.jar.entity.package")
Spring Boot doesn't really care whether the JPA entities are packages as a separate jar or included into the application. Its a runtime framework and in runtime classes can be loaded from the jar (it should reside in BOOT-INF/lib or 'directly' from the *.class files in the spring boot artifact.
Now there is a rule in spring boot, that says that it will scan for beans (including entities) only in the package where your "main" class resides or under it. This is done in order to avoid long process of analysis of, say, third-party classes that you might use. These third-party classes are usually not spring aware at all, at certainly do not contain any spring beans.
Example:
Say, you place your "main" class (the one annotated with #SpringBootApplication) in the package: com.mycompany.myapp
In this case, the following packages will be scanned (just a couple of examples):
com.mycompany.myapp
com.mycompany.myapp.web
com.mycompany.myapp.services.bl
com.mycompany.myapp.whatever.doesnt.matter
...
The following packages won't be scanned however (again, examples, not the full list):
com.mycompany
com.anothercompany
org.hibernate
If you want to to "alter" this default rule and place the entities in the package that doesn't adhere this convention, for example com.mycompany.jpa.entities then you should indeed use #EntityScan annotation as our colleagues have already suggested.
You can read about this topic here. You might also need to get familiar with #EnableJpaRepositories if you're using spring data but, while related, its a different topic.
In my case I had this problem, and after importing the library in the application's pom.xml, in the SpringBoot Project Main class, insert an #EntityScan annotation with the first package and *. Like this: #EntityScan ("br.*")

GWT hosted mode and tomcat deploy differences

I have a very specific problem dealing with GWT. I have a web application and a jar file which contains the business logic. Inside this jar I use dozer mapper and I have the related config file inside the jar itself. The config file is under META-INF/dozer_mappings.xml. While in hosted mode it works perfectly, in web mode it has a problem. It says:
Unable to locate dozer mapping file [/META-INF/dozer_mappings.xml] in the classpath!
Actually I don't understand why it should change: if the file is not in the classpath it should not work in both the environments... Of course all my libraries are in the WEB-INF/lib folder. The one with the dozer configuration is there as well.

Shared libraries between web services on Glassfish

I need to deploy multiple web services on a jax-ws application server, glassfish 3. These web services need to have shared libraries, meaning shared instances of the same class.
I know I could do this by dropping a jar in the "~/glassfish3/glassfish/domains/domain1/lib" directory. But I wonder whether this is possible in a more elegant way: I want to place the shared library jar inside a web service war which I deploy and then access that library from another war I deploy on the same application server.
How can I do this?
I found a solution for Glassfish myself: Basically I just deploy a class (SharedClassLoader) which inherits from URLClassLoader as a shared library jar in the above mentioned directory. Then I use this classloader as a bootstrap: On calling the web service, the classloader hierarchy is extended as follows: A SharedClassLoader for an URL is instantiated if it does not exist yet and it is added as a delegate to the DelegatingClassLoader in the classloader tree. By doing this for every web service with the same SharedClassLoader instance, it acts as a bootstrap to pull in more class loading. The jar that SharedClassLoader refers to can also be deployed with one of the web services, because Glassfish unpacks the containers to $AS_HOME/domains/domain1/applications/APPLICATION_NAME/LIBRARY_NAME.jar.
I hope this helps anyone having the same problem. I solved this problem for my Bachelor Thesis. If anyone needs more information, just ask, I can send you my thesis.

How to do Application specific Configuration for a Framework

i want to write a Java EE framework for a generic type of applications.
I'm looking for a way to handle application specific config values in my framework.
To give an example:
A component supplies a stateless session bean that handles persistence and i want to configure the name of the datasource that is used in a config file in my application (for example in the web-inf folder of the applications ear).
Now i have X>1 Applications that want to configure X different datasources for their specific persistence management.
Can anybody give me an example how to do that?
Greetings,
Alexander
You should use the JNDI provider thats bundled with the application container. One of its purposes it to access resources, data sources in your case, in a highly dynamic fashion.
For JBoss, setting up a data source involves the following steps:
deploy a *-ds.xml configuration file to the JBoss server's deploy directory. This defines the global JNDI name of the resources. There should be plenty of examples for a lot of databases available on the internet.
add a resource-ref to the jboss-web.xml of any WAR or to the jboss.xml of any EJB jar for any bean that needs the resource. This defines the global JNDI name to local/component JNDI name mapping.
add a resource-ref using the local JNDI name to the web.xml of any WAR or to the ejb-jar.xml of any EJB jar for any bean that needs the resource.
Once those things are in place, you can perform JNDI lookups to access the configured resource.
You can do these things to configure multiple data sources in JBoss and then make one or more of these data sources available to the web applications and EJBs.

deploy multiple RESTful service bundles in ServiceMix/FUSE 4.3

I am using the example cxf-jaxrs shipped with apache-servicemix-4.3.0-fuse-03-00.tar.gz to investigate how to deploy multiple bundles which provides different RESTful services. What I did is copied the cxf-jaxrs example into cxf-jaxrs-example-1, and modified the pom.xml and beans.xml. The modifications are :
1. pom.xml
version: 4.3.0-2-fuse-03-00
name: Apache ServiceMix Example 2:: CXF JAX-RS OSGI
2. beans.xml
<jaxrs:server id="customerService2" address="/crm2">
Then I made two packages. The one is the original example package cxf-jaxrs-4.3.0-fuse-03-00.jar and the other is the modified one cxf-jaxrs-4.3.0-2-fuse-03-00.jar and I copied them into "deploy" directory.
After servicemix started, I see both bundles are active and started succesfully.
But, I am only able to access the RESTful services in one bundle. When I type "http://localhost:8080/cxf/crm2/customerservice/customers/123", I got "No service was found." error. And when I stop the other example bundle(the original one), I can access "http://localhost:8080/cxf/crm2/customerservice/customers/123" with no problems.
What I did wrong?? It is supposed to provides the RESTful services in both context path "/crm" and "/crm2".
problem sovled. My bad. I forgot to modify the path annotation on CustomerService class