How do I specify my resourcesXml for Glassfish as a resource itself, and not a local file? - jboss-arquillian

I want to put all my configuration files (arquillian.xml, glassfish-resources.xml,test-persistence.xml) in a library and just reference that when i want to run a test in a project. But it seems the resourceXml only allows for a file-path and not a classpath: variable.
Is there a way to do that?
My configuration is currently based upon the arquillian-persistence-tutorial example project. I actually have no special configuration which is need. Just a in-memory db etc. etc.

I fixed it by extending the Arquillian class, and writing the resource to a local file (in the target folder) before any test.
Now in a domain project i only need to do this in a unit test:
public class MyEntityRepositoryImplTest extends BaseArquillianTest {
#Deployment
public static Archive<?> createDeployment() {
return create().//
addClass(MyEntityRepositoryImpl.class).//
addClass(MyEntityDaoImpl.class).//
addClass(MockSomeRepositoryImpl.class).//
addClass(MyEntityJpa.class);
}
#EJB
private MyEntityRepository myEntityRepository;
#Test
public void mMytest () {
}

Related

Arquillian - programmatic configuration

I am writing integration tests using Arquillian with embedded glassfish 3.1.2.2 using TestNG. I want to be able to run those tests in parallel, and for this case i need to dynamically configure glassfish ports and database name (we already have this set-up, and I want to reuse it of arquillian tests). What I am missing is a 'before container start' hook, where I could prepare the database, lookup free ports and update my glassfish configuration (domain.xml, could also be glassfish-resources.xml). Is there a 'clean' solution for this, or my usecase was not foreseen by Arquillian developers?
The hacky way I solved it currently is to override arquillian's beforeSuite method but this one gets called twice - at test startup and then in the container (therefore my pathetic static flag). Secondly, this solution would not work for JUnit based tests as there's no way to intercept arquillian's before suite:
public class FullContainerIT extends Arquillian {
private static boolean dbInitialized;
//#RunAsClient <-supported by #Test only
#Override
#BeforeSuite(groups = "arquillian", inheritGroups = true)
public void arquillianBeforeSuite() throws Exception {
if (dbInitialized == false) {
initializeDb();
dbInitialized = true;
}
super.arquillianBeforeSuite();
}
}
Some ideas I had:
+ having #BeforeSuite #RunAsClient seems to be what I need, but #RunAsClient is supported for #Test only;
+ I have seen org.jboss.arquillian.container.spi.event.container.BeforeStart event in Arquillian JavaDocs, but I have no clue how to listen to Arquillian events;
+ I have seen there is a possibility to have #Deployment creating a ShrinkWrap Descriptor, but these do not support Glassfish resources.
I found a clean solution for my problem on JBoss forum. You can register a LoadableExtension SPI and modify the arquillian config (loaded from xml). This is where I can create a database and filter glassfish-resources.xml with proper values. The setup looks like this:
package com.example.extenstion;
public class AutoDiscoverInstanceExtension
implements org.jboss.arquillian.core.spi.LoadableExtension {
#Override
public void register(ExtensionBuilder builder) {
builder.observer(LoadContainerConfiguration.class);
}
}
package com.example.extenstion;
public class LoadContainerConfiguration {
public void registerInstance(#Observes ContainerRegistry, ServiceLoader serviceLoader) {
//Do the necessary setup here
String filteredFilename = doTheFiltering();
//Get the container defined in arquillian.xml and modify it
//"default" is the container's qualifier
Container definition = registry.getContainer("default");
definition.getContainerConfiguration()
.property("resourcesXml", filteredFilename);
}
}
You also need to configure the SPI Extension by creating a file
META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
with this contents:
com.example.extenstion.AutoDiscoverInstanceExtension

Unit Testing from within Play-Module (JPA, eclipse PersistenceProvider)

My application is based on playframework and contains multiple modules.
The database interaction is handled trough JPA (<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>)
My task is to cover one of these modules with unit-tests.
Unfortunately running the "play test" command with unit tests provied on module-level results in the following Exception:
javax.persistence.PersistenceException: No Persistence provider for EntityManager named defaultPersistenceUnit
Persistence-Provider is defined globaly (outside of the Module) in conf/META-INF/persistence.xml
copying the global persistence.xml to the module doesn't fix the issue.
Placing the tests outside of the module (in global test directory) and execute them works flawless presuming that there are no other tests within modules.
Can someone explain me why the Error comes up? Is there any way to have working JPA-capable tests on module level?
Thanks in advance
Urs
I had the same problem running JUnit tests from my play application in Eclipse.
To solve this issue you need to make the folder conf available to the all project.
Project Properties-> Java Build Path ->Source
Add Folder and choose the conf folder.
I checked your code. I think don't need another persistence.xml. Can you try these solutions in play module:
#Test()
public void empty() {
running(fakeApplication(), new Runnable() {
public void run() {
JPA.withTransaction(new play.libs.F.Callback0() {
public void invoke() {
Object o = new Object(someAttrib);
o.save();
assertThat(o).isNotNull();
}
});
}
});
}
Or:
#Before
public void setUpIntegrationTest() {
FakeApplication app = fakeApplication();
start(app);
em = app.getWrappedApplication().plugin(JPAPlugin.class).get().em("default");
JPA.bindForCurrentThread(em);
}
These codes are from this page. I don't test it!
Please modify your code to:
#BeforeClass
public static void setUp() {
FakeApplication app = fakeApplication(inMemoryDatabase());
start(app);
em = app.getWrappedApplication().plugin(JPAPlugin.class).get().em("default");
JPA.bindForCurrentThread(em);
}
Please try it!

How can I configure a Swagger in Glassfish 4 without a web.xml?

The Swagger documentation covers a number of different ways to configure Swagger in an application. Unfortunately all of them leverage web.xml and rely on hard coding the api version and base url in the web.xml
Is there a way to configure Swagger without using a web.xml and without hardcoding the api version and base path?
I used the following approach to configure Swagger in Glassfish 4 without a resource XML.
Includes the following dependency in by gradle build file (this approach also applies to Maven):
compile ('com.wordnik:swagger-jaxrs_2.9.1:1.3.0') {
exclude group: 'org.scala-lang', module: 'scala-compiler'
}
Create a class that extends javax.ws.rs.core.Application and configure the ApplicationPath e.g.
#ApplicationPath("resources")
public class RESTConfig extends Application {}
2a. Create a class that extends com.wordnik.swagger.jaxrs.config.DefaultJaxrsConfig and annotate as follows:
#WebServlet(name = "SwaagerJaxrsConfig" initParams = {#WebInitParam(name="api.version", value="0.1.0"), #WebInitParam(name="swagger.api.basepath", value="http://localhost:8080/resources"})}, loadOnStartup = 2)
public class SwaagerJaxrsConfig extends DefaultJaxrsConfig{}
The downside of this approach is that the api version and base url of your app is hardcoded in the annotation. In order to get around this I used the following approach instead of the one above
2b. Create a class that extends HttpServlet and performs the bootstrapping done by DefaultJaxrsConfig e.g.
#WebServlet(name = "SwaggerJaxrsConfig", loadOnStartup = 2)
public class SwaggerJaxrsConfig extends HttpServlet {
private Logger log = Logger.getLogger(SwaggerJaxrsConfig.class);
#Inject Version version;
#Override public void init(ServletConfig servletConfig) {
try {
super.init(servletConfig);
SwaggerConfig swaggerConfig = new SwaggerConfig();
ConfigFactory.setConfig(swaggerConfig);
swaggerConfig.setBasePath("http://localhost:8080/resources"); //TODO look up app path
swaggerConfig.setApiVersion(version.getVersion());
ScannerFactory.setScanner(new DefaultJaxrsScanner());
ClassReaders.setReader(new DefaultJaxrsApiReader());
} catch (Exception e) {
log.error("Failed to configure swagger", e);
}
}
}

EJB Injection failure on deploy

I've got a problem exxh EJB's.
First of all, my setup: I am using GlassFish & JEE6. I have got a REST-Service packaged as a WAR and a bean packaged as an EJB-Jar. They are not inside an EAR.
The EJB should be used from the REST-WAR via #EJB, but when I try to deploy the WAR, GlassFish shows this error:
Error occurred during deployment:
Exception while deploying the app [exx-upload-1.0] : Cannot resolve reference Local ejb-ref name=com.ex.exx.model.FileUpload/ocr,Local 3.x interface =com.ex.exx.api.IOCRService,ejb-link=null,lookup=,mappedName=,jndi-name=,refType=Session. Please see server.log for more details.
(The EJB was deployed before without any erros).
I have no clue why. Here is the EJB Code:
Interface:
#Local
public interface IOCRService {
public String performOCRonImage(BufferedImage input);
}
and Implementation:
#Stateless
#LocalBean
public class OCRScanner implements IOCRService {
private Logger logger = Logger.getLogger(this.getClass().getName());
private final static String NOT_RECOGNIZED = "Can not regocnize text";
/**
* Default constructor.
*/
public OCRScanner() {
logger.log(Level.INFO, "### OCR SCANNER BUILD" + this);
}
public String performOCRonImage(BufferedImage input) {
logger.log(Level.INFO, "### OCR SCANNER CALLED" + this);
}
...
And here is the important part in the WAR:
public class FileUpload {
private final File PROPERTIES_FILE = new File(
"fileUploadProperties.properties");
private final String PARAMETER_NAME = "file";
private final Logger logger = Logger.getLogger(this.getClass().getName());
#EJB
private IOCRService ocr;
public Response uploadFile(...) {
// do some stuff
logger.log(Level.INFO, "### EJB" + ocr.toString())
}
Anny suggestions? I can not find my failure here.
Solved this, by replaceing #Local with #Remote.
This works, however, I am not satisfied as I do not understand why.
Basically, given the specs (eg. explained in the tutorial), an application can only access other application's EJB, if they are decorated with #Remote.
Thus, you have 3 options:
decorate your EJB with #Remote (what you have done),
package both together inside an ear (as they would reside in the
same application then). But if you intent to deploy them in seperate
applications or even seperate servers, use 1.)
use CDI with #Inject, but this will still only discover the EJB if
either in the same application, or decorated as #Remote if not.
HTH,
Alex
You should not use #EJB if the target is not an EJB. I guess this is your case because you are trying to inject into a class in your WAR.
Instead use:
#Inject
private IOCRService ocr;
Basically, #Inject is better in most cases, because:
it is more typesafe,
it supports #Alternatives
it is aware of the scope of the injected object.
Another solution it's to add #Stateless(name=""), this worked form

How to share fluent configuration in a Castle Windsor IOC container

I am trying to create an IOC container in Castle Windsor that's configuration is shared across assemblies.
(What follows is an example of how this works in Unity. What I want to do is to make it work the same way using Castle Windsor)
I have the following project configuration...
TestCompany.Services.Host
(Web project hosting a number of .svc files)
PrintService.svc
Web.Config
Unity.Config
TestCompany.Services.PrintService
IPrintService.cs
PrintService.cs
The actual implementation of my "PrintService" is not implemented inside my Services.Host but in the TestCompany.Services.PrintService assembly.
As part of my shared project code (not shown) I have a container helper which is responsible for loading the unity configuration...
public static IUnityContainer GetContainer()
{
// Checks for existance of container (_container == null) ommitted.
var section = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;
section.Configure(_container, name);
...
...
}
This method loads the unity configuration section from the Unity.Config and uses it to configure the container.
The advantage of this method is that one Unity.Config loaded inside (I presume) the AppDomain can service a number of assemblies. Simply calling GetContainer() from any of the assemblies consumed by my service host will return a container populated with the same type resolution's etc.
I really want to use the fluent configuration in Castle Windsor but I dont see how without this "shared" configuration file that can be acheived. PrintService and any future services will all need to resolve the same dependencies and I dont want to have to repeat my fluent configuration between these services.
Ideally I need some sort of container configured in the service host app that can "flow" into all of the assemblies that it makes use of.
Thanks.
I think I may not be understanding your question but I think I understand your scenario and here is how I do something similar, if it helps at all...
My Philosophy:
Each part of the application should be in charge of registering what
it knows about and nothing more, so there is no need for a single
central configuration file and things that are shared between
components are registered in one place and their interfaces are
available everywhere via a common library.
So let's take an example...
First of all, let us just say (for the purposes of my example) that IPrintService is something that you want to register an implementation of once and use throughout the application and that we have some other component that needs to be implemented by some external module from the main application. We, therefore, create an assembly called Common like so:
Common
public interface IPrintService
{
void Print();
}
public interface IMyService
{
void DoSomething();
}
Now let us think about the main part of the application (maybe it is an ASP .NET application, maybe justa console application, does not really matter). Here we construct the container and ask it to find all the possible components. We can do that like so:
Main Application
// Could be the Global.asax code behind but for simplicity this is
// just a console application
class Program
{
private static readonly IWindsorContainer Mycontainer
= BootstrapContainer();
// Allow access to the raw container - this is probably a bad idea but
// in the rare case that you need it you can get it from here
public static IWindsorContainer Container { get { return Mycontainer; } }
private static IWindsorContainer BootstrapContainer()
{
// Here we will just install every IWindsorInstaller found in any
// assembly in the same folder as the application (so no need for
// references or anything).
var c = new WindsorContainer();
string folder = Path.GetDirectoryName(
Assembly.GetExecutingAssembly().Location);
c.Install(FromAssembly.InDirectory(new AssemblyFilter(folder)));
return c;
}
}
// Here is the print service implementation
public class MyPrintService : IPrintService
{
public void Print()
{
// Print!
}
}
// This is the installer for the main module - here we are saying exactly
// what is implementing the interface
public class MainApplicationInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container,
IConfigurationStore store)
{
container
.Register(Component
.For<IPrintService>()
.ImplementedBy<MyPrintService>());
}
}
So now we have a common library with our shared inetrfaces and a main application that will register an implementation for our shared interface and also load up any other modules in the system.
The only thing, therefore, left to do is to consume that print service and use it. We can do this anywhere that is using the container so let's create a third assembly that references only Common (we will call it test module.
Test Module
// This installer installs just the things inside this module since that
// is all it knows about but those things can use things that are
// registered in the container by anybody.
public class TestModuleInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container,
IConfigurationStore store)
{
container
.Register(Component
.For<IMyService>()
.ImplementedBy<MyServiceThatDoesSomething>());
}
}
public class MyServiceThatDoesSomething : IMyService
{
private readonly IPrintService _printService;
public MyServiceThatDoesSomething(IPrintService printService)
{
_printService = printService;
}
public void DoSomething()
{
// Use the print service!
_printService.Print();
}
}
Finally compile everything and copy the test module to the same folder as the main application and then from the main you can do this:
Container.Resolve<IMyService>().DoSomething();
And then the magic happens! Well, some code runs and you find that the print service is called by the class from the module even though it knows nothing about it.
Anyway, maybe that helps a little bit, maybe not, good luck!