Buildr JVM properties for JUnit set inside the JVM rather than outside - properties

When using JUnit we pass the directory used for logging as a JVM property. This works fine on the command line and in Eclipse. However, it doesn't work when we pass the same property to the Buildr test task.
test.using :properties => { :"server.name" => "tester", :"log.dir" => log_dir}
We know why this happening. The property is being set from inside the JVM rather than outside. This means that at run time (when the static logging class is loaded) the property is not yet set. If we query the property later (say from within a unit test) then we see that it is set correctly.
Does anyone know of a workaround?
BTW, we're using log4J but the question is applicable to any static class that needs access to a JVM property set by Buildr.

Assuming that you are using JUnit, you can ensure that the tests run in a forked JVM via
test.using :fork => :once
However I thought that was the default behaviour? Are you overriding this somehow? (See http://buildr.apache.org/languages.html)

this code defines the log.dir in the log4j.properties file and sets it in the buildfile via
test.using :properties => { :"log.dir" => '/tmp'}
my setup is
buildr 1.4.7
ruby 1.9.3
hth

Related

How to provide an HttpClient to ktor server from the outside to facilitate mocking external services?

I am trying to provide an HttpClient from the outside to my ktor server so that I can mock external services and write tests, however I get this exception when I run my test:
Please make sure that you use unique name for the plugin and don't install it twice. Conflicting application plugin is already installed with the same key as `Compression`
io.ktor.server.application.DuplicatePluginException: Please make sure that you use unique name for the plugin and don't install it twice. Conflicting application plugin is already installed with the same key as `Compression`
at app//io.ktor.server.application.ApplicationPluginKt.install(ApplicationPlugin.kt:112)
at app//com.example.plugins.HTTPKt.configureHTTP(HTTP.kt:13)
at app//com.example.ApplicationKt.module(Application.kt:14)
at app//com.example.ApplicationTest$expected to work$1$1.invoke(ApplicationTest.kt:39)
at app//com.example.ApplicationTest$expected to work$1$1.invoke(ApplicationTest.kt:38)
and thats a bit unexpected to me because I am not applying the Compression plugin twice as far as I can tell. If I run the server normally and manually call my endpoint with curl then it works as expected. What am I doing wrong?
I added a runnable sample project here with a failing test.
sample project
official ktor-documentation-sample project.
The problem is that you have the application.conf file and by default, the testApplication function tries to load modules which are enumerated there. Since you also explicitly load them in the application {} block the DuplicatePluginException occurs. To solve your problem you can explicitly load an empty configuration instead of the default one:
// ...
application {
module(client)
}
environment {
config = MapApplicationConfig()
}
// ...

getClassPath() method in the WebLogic context class loader does not consider package preferences in weblogic.xml

A related problem: Get the class path from the context class loader (of WebLogic for instance)
This is already solved in How to set up the context class loader's classpath for runtime compilation?.
Current problem: Get the same (proper) class path used to run a web app
Reflectively calling the "getClassPath()" method works but it returns a dirty classpath containing unanted modules from $ORACLE_HOME/oracle_common/modules directory.
Problematic scenario:
Deploy a web app "Parent" in WebLogic // <- works
Get the context class path (it's a String object) by reflexively calling "getClassPath()" // <- works
Fork a process out of the main "Parent" process and run it using the context class path // <- fails
04:36:45,238 [Thread-41] ERROR ChildProcess - Exception in thread "main" java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.ObjectMapp
er.configOverride(Ljava/lang/Class;)Lcom/fasterxml/jackson/databind/cfg/MutableConfigOverride;
Explanation
While the context class path contains the necessary dependencies for the child process to run, they are overshadowed by WebLogic's own dependencies. The result is runtime failures such as the one shown above.
Workaround
a) Use a new version of WebLogic server that hopefully would use newer versions of the artifacts needed by the child process // risky endeavour
b) Manually process the context class path and remove any artifact that would shadow their more-recent counterparts
Solution b) looks more practical, but I don't like it for meany reasons:
The reflexive call to "getClassPath" returns a String, and looking for artifact's names in Strings feels frail and weak
I wouldn't know what shadows what. WebLogic prepends its weird artifacts at the start of the string before listing the web app's own dependencies.
Only weblogic.xml has info on the web app's package preferences. I wish I could mimic how WebLogic processes this file to run the web app (Parent) and use that to properly run the child process
It seems to me that forking a process out from a web app running in WebLogic does not enjoy the same package preferences expressed in "weblogic.xml" that the web app (Parent) enjoyed when it was deployed and started running.
Other than the above suggestions, I am welcoming of any stronger solutions

Load elixir configs hierarchal in multiple projects

I am writing a small project in Elixir, where I will use the built in configuration capability. The way it looks like I have a general project that will call APIs:
api/confix.exs:
use Mix.Config
config :api, :status, "awesome"
I now have a second project that should utilize these variables
api_consumer/mix.exs
def application do
[applications: [:logger, :api]]
end
When I run a console in api_consumer accessing the variable yields a nil result.
iex -S mix
iex(1)> Application.get_env(:api, :status)
=> nil
From what I understand (and from what I read here) that should work.
Does anybody know what's going on here?
mix.exs is used to configure the current application, while config.exs is used to configure other applications. In your :api application, you should put the default values in the application/0 function inside mix.exs:
# api/mix.exs
def application do
[
applications: [:logger, :api],
env: [status: "awesome"]
]
end
Then, you can override this setting in your :api_consumer application inside the config.exs file:
# api_consumer/config/config.exs
config :api, status: "fantastic"
More info can be found here.

JRuby - disable Apache Common Logging

I'm trying to disable Apache Common Logging in JRuby this way:
require 'java'
...
module ...
java_import org.apache.commons.logging.Log
java_import org.apache.commons.logging.LogFactory
java::lang.static {
java::lang.System.setProperty("org.apache.commons.logging.Log",
"org.apache.commons.logging.impl.NoOpLog")
}
based on Java code:
static {
System.setProperty("org.apache.commons.logging.Log",
"org.apache.commons.logging.impl.NoOpLog");
}
In Java above code disables logging but in JRuby logging is still enabled.
the java::lang.static just does nothing (it works since JRuby needs to lazily allow package names since it can not know before-hand which packages will exists until a class is loaded from a given package).
in Ruby and thus JRuby there's no static initializers - code is executed as it's parsed thus simply do a (no need for the java_imports neither since you're not using those classes) :
java::lang.System.setProperty("org.apache.commons.logging.Log",
"org.apache.commons.logging.impl.NoOpLog")

how to invoke a play application without hitting the URL (http request)?

I'm using play application (using Play version 2.1.0) with RabbitMQ and do not have any view component.
So i would like to invoke this play application without hitting the execution URL (http://localhost:9000/<routing_info>) on server startup.
Would also like to know if there is any way in Play 2.1.0 version to run the application on server startup, i mean bootstrapping. Is this option available in play 2.1.0.
As i've read through the documentation its mentioned only for 1.2 version.
Please help!!
Play allows you to define a 'global' object which will be instantiated automatically by Play when the application starts.
In application.conf you should find the following:
# Global object class
# ~~~~~
# Define the Global object class for this application.
# Default to Global in the root package.
application.global=global.Global
On a new play application, this line is commented out. I've uncommented it and made it point to an object called Global in the global package. You can make it what ever you want.
Your global object should extend GlobalSettings.
In my applications, I use a static initialiser block to run code when that class is loaded:
public class Global extends GlobalSettings
{
static
{
...
}
}