Why is OpenLiberty datasource not available in unit tests? - junit

OpenLiberty is running in dev-mode.
Somewhere in my code i use
Context initContext = new InitialContext();
DataSource ds = (DataSource) initContext.lookup("app/myDB");
with a datasource configured in the webserver:
<dataSource id="mssql" jndiName="app/myDB">
<connectionManager maxPoolSize="20000" minPoolSize="2"/>
<jdbcDriver libraryRef="MSSQL"/>
<properties.microsoft.sqlserver databaseName="myDB" serverName="xxx.xxx.xxx.xxx" portNumber="1433" user="X" password="Y"/>
</dataSource>
This works fine so far, until i try to run my units tests.
When trying to run the tests on demand, that somewhere call this code:
Context initContext = new InitialContext();
DataSource ds = (DataSource) initContext.lookup("app/myDB");
my webapp fails with
javax.naming.NoInitialContextException
So why do the unit tests do not have the initial context? Can i somehow tell OpenLiberty to provide that resource for test scope? Or do i have to mock the initialContext? I am a beginner in writing unit/integration test. If i need to provide additional information please tell me.
edit: added dev-mode and general clarification

In order for a DataSource to be made available for JNDI lookups in Liberty, you need to have the Liberty server running and the jndi-1.0 feature enabled, and one of the jdbc-4.x features enabled. For example, in server.xml,
<<server>
<featureManager>
<feature>jndi-1.0</feature>
<feature>jdbc-4.2</feature>
... other features
</featureManager>
...
</server>

Related

Quartz 2.6.2 and .NET Core? - Error "Could Not Initialize DataSource"

I'm using an older version of Quartz.NET (v2.6.2) with .NET Core (or possibly .NET5). I'm getting an error when attempting to use the StdSchedulerFactory.GetScheduler. All my configuration settings are within my appsettings.json where I populate a NameValueCollection with these values and inject them into my classes with DI.
["quartz.scheduler.instanceId"] = "instance_one",
["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz",
["quartz.threadPool.threadCount"] = "5",
["quartz.jobStore.misfireThreshold"] = "60000",
["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz",
["quartz.jobStore.useProperties"] = "false",
["quartz.jobStore.dataSource"] = "default",
["quartz.jobStore.tablePrefix"] = "QRTZ_",
["quartz.dataSource.default.provider"] = "SqlServer-20",
["quartz.dataSource.default.connectionString"] = quartzConn
I am using the StdSchedulerFactory like this, where Settings.Properties is that NameValueCollection which contains all the config settings:
var factory = new StdSchedulerFactory(Settings.Properties);
var scheduler = factory.GetScheduler();
On the GetScheduler method, the error, "Could Not Initialize Datasource: default" is thrown.
The crazy thing is this code works fine in a Framework 4.x project that uses a regular web.config to supply the configuration settings. Also, when I change to use Quartz 3.X with my code above, with configurations in the appsettings.json works fine. Seems that me mixing and matching both versions is causing an issue where Quartz doesn't know how to retrieve some value?
Is there a way to manually build my scheduler and not use the factory?
Thanks!
I've had to go back to Framework 4 and Quartz 2.6 to get them to play nicely together. I can only get Quartz 3.x to work with .NET Core/5. Stepping through the source code with dotPeek, Quartz 2.6 is using ConfigurationManager to pull web.config details that don't exist in Core/5. At this point I don't remember if I tried to add my own web.config file to this project or not, but I've since moved on.

SQL traces not shown in junit

I am working on an application using EJB and OpenJPA. FOr unit testing I use junit.I am running junits using Websphere's embedded container.
EJBContainer.createEJBContainer(map containing db properties);
In persistence.xml I have set :
<property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE" />
I expect SQL traces in console, but no traces are shown.
What else do I need to do for SQL traces?
I'd start by reading the knowledge center documentation. From what I recall, you need to use WAS logging rather than OpenJPA p.xml configuration.

MySql pooled datasource in standalone JAVA app (no J2EE container, no JNDI, no TOMCAT etc.)

I've been reading dozens of topics here with no real enlightment: I'm running a standalone java app, on a Synology NAS with Java 8. I also installed MariaDB on the same NAS. So everything is local.
I am able to setup a datasource and get a connection, but I would like to be able to access it in any instance of any of my classes / threads for connection pooling. Everything seem to show that I would need JNDI. But I don't have a J2EE container and this seems overkill for my need. Idem for developping my own implementation of JNDI.
I've seen replies to similar questions where people suggest C3PO. But this is just another datasource implementation. I don't think it solves the standalone app issue with no way to access datasource from anywhere in the code :
How to retrieve DB connection using DataSource without JNDI?
Is there another way to share a datasource across java threads ?
Can I pass the Datasource instance as a parameter to each thread, so
they can get a connection when they need ?
Should I assign a given connection to each thread - also passed as a
parameter ? and in this case, never really close it properly ?
Or should I really install something like tomcat, jboss, jetty ? are
they equivalent ? Is there a super light J2EE container that could
provide JNDI ?
Thanks
Vincent
You could use the singleton pattern, like this for example:
public class DataSourceFactory {
private static DataSource instance = null;
private DataSourceFactory() { }
public static synchronized DataSource getDataSource(){
if(instance == null){
instance = // initialize your datasource
}
return instance;
}
}
Then any from any thread you can call DataSourceFactory.getDataSource() to get a reference to your DataSource object.

CloudFoundry MySQL Java configuration

I have a Spring MVC app that is running fine on local tomcat etc. Its a Spring 3.1 MVC/Hibernate app.
I am using (where possible) pure Java #Configuration for the app - and I am now trying to deploy the app to CloudFoundry (via STS), but I am struggling to get the MySql db configured (from memory, with xml config you dont need to do anything and Spring/CloudFoundry auto-injects the required user/password etc, but its been a while since I deployed anything to CF).
I have tried both of the following configurations:
#Bean
public BasicDataSource dataSource() throws PropertyVetoException {
//CloudFoundry config
final CloudEnvironment cloudEnvironment = new CloudEnvironment();
final List<MysqlServiceInfo> mysqlServices = cloudEnvironment.getServiceInfos(MysqlServiceInfo.class);
final MysqlServiceInfo serviceInfo = mysqlServices.get(0);
BasicDataSource bean = new BasicDataSource();
bean.setDriverClassName("com.mysql.jdbc.Driver");
bean.setUrl(serviceInfo.getUrl());
bean.setUsername(serviceInfo.getUserName());
bean.setPassword(serviceInfo.getPassword());
return bean;
}
The above failed on out of bounds on the .get(0) line of the mysqlServices. This was based on the answer suggested here.
I also tried leaving the datasource as what it runs on as local to see if the properties just get injected, but no luck there either. (the below was tried with the values as per the Spring sample code here, and also using property placeholders from my db.connection props file)
#Bean
public BasicDataSource dataSource() throws PropertyVetoException {
BasicDataSource bean = new BasicDataSource();
bean.setDriverClassName("com.mysql.jdbc.Driver");
bean.setUrl("");
bean.setUsername("spring");
bean.setPassword("spring");
return bean;
}
Edit
I have also used the getServiceInfo(String, Class) method passing in the name of the MySql service that I have created and bound to the application, but that just NPEs similar to the getServiceInfos(..) approach
Ok, this was just a stupid mistake - when I deployed the app via STS I had selected Java Web app rather than the "Spring" type. Not sure why that would make the CloudEnvironment properties not be available (I was under the impression that approach was the common method to inject the details in non-Spring apps) - but re-deploying it to the server as a Spring app resolved the probs!

Castle Windsor Configuration Over Multiple Projects and unit testing

I have a solution with multiple projects and one of these projects is my service class which calls into the persistence manager.
I would like to write a unit test as follows:
[Test]
public void Create_HappyPath_Success()
{
// Arrange
UnitOfMeasure unitOfMeasure = new UnitOfMeasure();
unitOfMeasure.Code = "Some new unit of measure";
unitOfMeasure.DataOwner = 1;
// Act
this.UoMService.Create(unitOfMeasure); // Fails here as UoMService is null
// Assert something
}
Now, I'm getting a null reference exception on this line:
this.UoMService.Create(unitOfMeasure); // Fails here as UoMService is null
I believe that it's due to the fact that Castle Windsor is not getting called and hence the UoMService isn't getting instantiated. My Castle Windsor application installer is defined in another project i.e. my ASP.NET MVC project. So my first question is whether it's possible to reuse that installer to run my Unit Tests.
Now to get around this problem, I created a new installer in my unit test project by linking to the installer in my web project. Then I used the following code in my set up:
[SetUp]
public void ControllersInstallerTests()
{
this.containerWithControllers = new WindsorContainer();
IoC.Initialize(this.containerWithControllers);
this.containerWithControllers.Install(FromAssembly.This());
}
This time when I run the tests, I get the following error:
SetUp : Castle.Windsor.Configuration.Interpreters.XmlProcessor.ConfigurationProcessingException : Error processing node resource FileResource: [] []
----> Castle.Core.Resource.ResourceException : File C:\Projects\DavidPM\Services\MyProject.Services.ServiceImpl.Test.Unit\bin\Debug\Config\Windsor.config could not be found
The question is why is it looking in the bin\Debug folder?
As a newbie with Castle Windsor, I am not sure what I should be doing to hook into Castle Windsor for my unit tests.
You should not be hooking up your IoC container in your unit tests. During production, your IoC container will resolve dependencies. During unit tests, you create the dependencies as part of your tests -- usually using a mocking framework so you can test in isolation.
make your config file copy to output directory