JRuby - disable Apache Common Logging - apache

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")

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()
}
// ...

grails / groovy console VS war file Ambiguous method SQL

So working with grails run-app VS war file.
My expectation was that all I have to do to generate a war file and throw it into Tomcat was to type in war
Code below works fine on the RUN-APP console. Code stripped down to what is not working.
package foo
import groovy.sql.Sql;
class FooAlertJob {
static triggers = {
simple name: 'mySimpleTrigger', startDelay:5000, repeatInterval: 1000*10l
}
def dataSourceFoo
def execute() {
def sql = new Sql (dataSourceFoo)
}
}
When running with tomcat and a war file built from grails I am getting (pasted below)
Cannot resolve which method to invoke for [null] due to overlapping prototypes between:
[interface javax.sql.DataSource]
[interface java.sql.Connection]]
Googling around I did not find a solution so perhaps I am just dense.
What do I have to do to my groovy so that when I generate a war file I do not have to worry about re-testing it all ?
I have tried the obvious about fully qualifying sql as groovy.sql.SQL but I do not have a clear example of working code from run-app to war file.
Also frustrating is the groovy / grails docs does not even mention it so I am wondering if I just don't understand basics here. I am clear on runtime groovy VS compile time but still you would think that examples you copy/paste from grails documentation would work if you produced a war file.
java 1.8
Grails 2.5.3
Groovy 2.4.5
[interface java.sql.Connection] [See nested exception: groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method groovy.sql.Sql#.
Cannot resolve which method to invoke for [null] due to overlapping prototypes between:
[interface javax.sql.DataSource]
[interface java.sql.Connection]]
war file generated by Grails ignores dataSource URL
Looks like it was a palm slap to the forehead.
The Datasource needs to be defined in the production environment as that is what the war file is expecting.
Thanks everyone.

Jython does not resolve python imports from bundled Lib files/folders on Weblogic 10.3.5

I am new to Jython and Python, trying to build a prototype that makes use of Python code to be called from within Java. The code I am developing works in Jetty and in standalone mode (running java -jar from the command line), but not when deployed to weblogic.
How can I make weblogic(10.3.5) server/Jython recognize the Lib folder within jython-standalone-2.5.4-rc1.jar?
My Java code uses the JythonObjectFactory to invoke python modules as outlined in the Jython book:
http://www.jython.org/jythonbook/en/1.0/JythonAndJavaIntegration.html
The Python modules are using external libraries like csv, logging etc. that are not packaged with jython.jar, hence I am using jython-standalone jar.
The java code includes an interface that would define the class type of the first invoked py module from within java. The interface and the input and output (to python modules) type classes are in a package structure as com.abc.xpackage. and the py modules exist at the root of this package. A controller layer calls the objectfactory and in turn executes the python code thus:
JythonObjectFactory calFactory = new JythonObjectFactory(CalcType.class, "Calculate", "Calculate");
CalcType engine = (CalcType)calFactory.createObject();
output = engine.execute(input);
The entire code is bundled as a jar file which would become part of a web application deployed on weblogic. The code was compiled with maven (with jython dependencies included in the repository) and runs fine on the included Jetty runtime within eclipse.
When deployed on weblogic, however, I get a "ImportError: no module named csv" error.
To analyze what is happening, I tried printing the Jython system state path on weblogic and the standalone environment/Jetty. What I found is,
on Jetty, the system path consists of the following:
C:\.m2\repo\org\python\jython\jython-standalone-2.5.3-rc1.jar\Lib, ____classpath__, ____pyclasspath__
on Weblogic, printing the system path by default shows the following:
____classpath__, ____pyclasspath__
I tried forcing the inclusion of the missing path using the code as follows:
public JythonObjectFactory(PySystemState state, Class interfaceType, String moduleName, String className) {
String pathToAppend = new File(state.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getAbsolutePath()+"\\Lib";
state.path.insert(0, new PyString(pathToAppend));
state.path.append(new PyString(pathToAppend));
System.out.println("Jython sys path: "+state.path);
Please note, I prepended as well as appended the path in different trials. The sys path on weblogic now displays the following:
Jython sys path: ['C:\\wldomain\\wls135\\servers\\cgServer\\tmp\\app-1\\war\\WEB-INF\\lib\\jython-standalone-2.5.4-rc1.jar\\Lib', '__classpath__', '__pyclasspath__/', 'C:\\wldomain\\wls135\\servers\\cgServer\\tmp\\app-1\\war\\WEB-INF\\lib\\jython-standalone-2.5.4-rc1.jar\\Lib']
I am still getting ImportError despite this forcing of sys path. Please help why this works in a local environment, and not on weblogic, and if there is any configuration I am missing. Apologize for the rambling long post, I did not know how to explain the problem better. I will try and include any code/artifacts as needed.
Based on a comment(by Lassi) on the blog post below:
http://www.petervannes.nl/files/e1c3c56d15d25dcfd4adb5397a9ef71e-53.php
The jython issue was resolved after explicitly adding the Lib folder python.path to the weblogic startup script as a JAVA_OPTION.
In my case I added the exploded Lib folder to the domain server lib, but based on my test this works also from within the jython jar. Both the following JAVA_OPTIONS worked:
-Dpython.path=C:\wldomain\wls135\lib\Lib
-Dpython.path=C:\wldomain\wls135\lib\jython-standalone-2.5.4-rc1.jar\Lib
The programmatic way of sys.path.append worked for the local environment(jetty) but did not seem to work for weblogic.

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
{
...
}
}

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

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