Java 7: using URLClassLoader not working anymore - classloader

my problem is, that my code which was working on Java6 does not work any more.
Since my app needs to load jar's at runtime (plugins), i wrote myselt a simple class deriving from URLClassLoader like this
public class MyClassLoader extends java.net.URLClassLoader {
/** Creates a new instance of URLClassLoader */
public MyClassLoader(java.net.URL url)
{
super(new java.net.URL[]{url},ClassLoader.getSystemClassLoader());
}
public void addURL(java.net.URL url)
{
super.addURL(url);
}}
So if i want load a jar, i simply call addURL(pathToJar) and load that class via
Class.forName(myClass, true, myClassLoader)
This worked like a charm running on Java6.
Now i decided to make a self contained java app in Java7.
When I start the app, the jar's also get loaded at runtime, but if there's a class inside which derives from a class that is inside the classpath (not in the plugin jar) i get a ClassCastException.
So i guess something has changed in Java7.
At the moment I'm using Java7_u13 on OSX.
Can any one give me a hint on what I should do, to get the old behaviour back? Searching the net didn't get me any help yet.
Many thanks in advance.
Greetings, -chris-

Meanwhile i found the solution to my problem. I just used the 'wrong' classloader as the parent. Everything now works fine if i replace
super(new java.net.URL[]{url},ClassLoader.getSystemClassLoader());
with
super(new java.net.URL[]{url},MyClassLoader.class.getClassLoader());
Greetings, -chris-

Related

EnableNeo4jRepositories.sessionFactoryRef is ignored / does nothing

I'm trying to configure a Spring Boot 1.5.9 project with multiple data sources, of which some are Neo4j.
The version of spring-data-neo4j I'm using is 4.2.9.
My goal is to use a different SessionFactory for different repositories, using a different Configuration class for each.
I've got this all working with Mongo but it seems that, even though the sessionFactoryRef is available on #EnableNeo4jRepositories, it simple does not get acted upon.
Abbreviated version of my configuration, with the general concepts:
#org.springframework.context.annotation.Configuration
#EnableNeo4jRepositories(basePackages = "<repo-package-name>", sessionFactoryRef = NEO4J_SESSIONFACTORY_NAME)
public class MyConfiguration {
protected static final String NEO4J_SESSIONFACTORY_NAME = "mySessionFactory";
#Bean(NEO4J_SESSIONFACTORY_NAME)
public SessionFactory mySessionFactory() {
SessionFactory sessionFactory = ...
// passing entity package corresponding to repository
return sessionFactory;
}
As mentioned, this construct works fine with spring-data-mongodb, however in neo4j it first starts out with an error:
***************************
APPLICATION FAILED TO START
***************************
Description:
A component required a bean named 'getSessionFactory' that could not be found.
Action:
Consider defining a bean named 'getSessionFactory' in your configuration.
Turning on debug in the logger and a look through the code led me to SessionBeanDefinitionRegistrarPostProcessor, that contains the following code to get the sessionFactory:
private static String getSessionFactoryBeanRef(ConfigurableListableBeanFactory beanFactory) {
return beanFactory.containsBeanDefinition("sessionFactory") ? "sessionFactory" : "getSessionFactory";
}
Hmmm... hardcoded names for a bean, no sign of customisability.
I then proceeded to name my bean twice, #Bean("sessionFactory", NEO4J_SESSIONFACTORY_NAME), so the above code would pass.
The application started, but the problem is that the repositories get wired with whatever bean is called sessionFactory, effectively not using the sessionFactoryRef on the annotation.
To test this, I changed the name on the annotation to a non-existing bean and it continued to start (if I do this with the mongo-annotation, the application quits because the bean mentioned in mongoTemplateRef isn't available).
I dug a little deeper and found that, for mongo, it retrieves the bean reference in this class. The equivalent neo4j implementation has no such thing. It could of course be an implementation detail but I wasn't able to find any reference to the sessionFactoryRef attribute other than the annotation and the xml-schema.
There are also other places in the config classes that expect only one SessionFactory to be available.
So, in short, it seems to me that EnableNeo4jRepositories.sessionFactoryRef has no implementation and therefore simple doesn't do anything.
As a result, with the current code a single bean "sessionFactory" must be present and all repositories will be wired with this bean, regardless of the value of sessionFactoryRef.
Anybody else with a similar experience or any idea how to file a bug for this?

Eclipse plug-in development - unit testing e4 parts

I am trying to test an Eclipse plug-in with a E4 style view. I have created a test class inside a JUnit plug-in Test run configuration. But I'm struggling to even open the view. The old e3 way was to use the following snippet to open views:
PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getActivePage().showView("some view id")
In e4, we can use a EPartService (documentation) instead. However, I'm not sure how to access it. Trying to inject it does not work. This is what I have tried:
public class MyTest {
#Inject EPartService partService;
#Test
public void testOne() {
// partService is still null here...
I've also tried adding the #PostConstruct annotation to the test method, with no luck. Shouldn't this work, since it is running as a JUnit plug-in test, which I assume has an Eclipse context with a part service ready?
According to this article, it should also be possible to create a Display class and an associated Shell, which can be passed to the view's createPartControl method. I have tried this in the test method as well:
Display display = Display.getCurrent();
Shell shell = new Shell(display);
IEclipseContext context = EclipseContextFactory.create();
IPartService partService = mock(IPartService.class);
context.set(IPartService.class, partService);
context.set(Composite.class, shell);
view = ContextInjectionFactory.make(InspView.class, context);
shell.open();
I need the IPartService (not to be confused with the EPartService...) because the view needs it. This actually works. But, as you can see, I need to mock an IPartService and hand it to the Eclipse context. This does not give me what I want. Instead, I want an Eclipse context with all the services instantiated. Is this possible? Which approach is the most correct? Using Display+Shell, or EPartService?
Thanks!
UPDATE:
It is possible to open the part using the following:
EPartService partService =
PlatformUI.getWorkbench().getService(EPartService.class);
partService.showPart(VIEW_ID, PartState.ACTIVATE);
Is that a good approach?

Http.Context with FakeApplication and illusive mock method

In my tests I create a fake application per test method:
#Before
public void startFakeApplication() {
this.fakeApplication = fakeApplication();
start(this.fakeApplication);
}
#After
public void killFakeApplication() {
stop(this.fakeApplication);
this.fakeApplication = null;
}
Some of the tests use functionality that checks if the request is secure or not:
public boolean isHttps() {
Http.Request req = Controller.request();
return req.getHeader("x-forwarded-proto") != null
&& req.getHeader("x-forwarded-proto").contains("https");
}
That fails saying:
There is no HTTP Context available from here
Which is pretty strange, since it's running on a fake app, why can't it know that and create a fake request?
Oh well, I found this: Play framework 2.2.1: Create Http.Context for tests which introduced me to the mocking approach, so I was eager to give it a go and try to mock the Http.Context in the same way, the problem is that I can't seem to find the mock method...
In that thread he's using import static org.mockito.Mockito.* (which is where I assume the mock method is located) but I don't have that package, org.mockito only has one sub package named internal and I can't find any mock method there.
In the official documentation of Play! the only place talking about it is the Scala Test section and they use: import org.specs2.mock._ but there too I wasn't able to locate this mock method.
I'm using Play 2.2.2 (java).
Any ideas? Thanks.
I solved the same problem adding to my build.sbt the library dependency of Mockito:
libraryDependencies += "org.mockito" % "mockito-core" % "1.10.19"
Then I run play compile and play eclipse and magically the mockito library became available after refreshing the whole project in Eclipse.
And yes, mock() is a method of org.mockito.Mockito.
I had the same problem of Play not locating the mock function, and eventually realised that I hadn't extended my test class with Mockito;
import org.specs2.mock._
class TestClass extends Specification with Mockito
Just thought I'd add this as it has taken me ages to resolve and the above solution didn't work for me ......may save someone some time :)

Extending PHPUnit_Framework_TestCase while using dataProviders

I'm fairly new to using PHPUnit and I'm trying to use it more effectively by using data providers. I can get data providers to work when writing a normal test case, however I find that I'm rewriting my setup code for across several testcases. So I'm trying to extend PHPUnit_Framework_TestCase with a BaseTestCase class that does all of my common setup. This works if I run simple test in a test case that extends my BaseTestCase class. However I can't seem to use #dataProvider when extending my BaseTestCase class.
So my setup is:
class BaseTestCase extends PHPUnit_Framework_TestCase{
public static function setUpBeforeClass(){
//do setup
//this is getting called and it works
}
}
class myTest extends BaseTestCase{
public function myBasicTest(){
//this works
$this->assertEquals(2, 1+1);
}
public function myProvider(){
return [
[1,1,2],
[1,2,3],
[1,4,5],
]
}
/**
* #dataProvider myProvider
*/
public function testMyProvider($a, $b, $result){
//this doesn't work, the provider never gets called
//this would normally work if I extended PHPUnit_Framework_TestCase
$this->assertEquals($result, $a+$b);
}
}
I know the providers get ran before any of the setup does so I'm wondering if PHPUnit doesn't know that the provider exists because of the inheritance. Either way, does anyone know if what I'm trying to do is possible this way or does PHPUnit have another way of accommodating these types of situations?
Thanks for your help,
Jordan
Your test function does not begin with the word 'test'.
public function test_myProviderTest($a, $b, $result){
This is actually a non issue. I had an incorrect constructor setup in my test file. A very frustrating oversight.

How can I create a class method using AppleScriptObjC

I'm trying to override the +initialize method of a class using ASOC, but I cannot find a way to override a class method. Is it even possible?
Not to let any confusion possible about the language I'm talking about, here's some code:
script FLAppDelegate
property parent: class "NSObject"
-- -- Class Methods -- --
-- Insert code here
end script
I've done some tests, and as far as I can tell, weird as it is, methods defined using AppleScriptObjC are both class and instance methods.
Let's say I have an AppleScriptObjC file:
script iTunesController
property parent: class "NSObject"
on playpause()
tell application id "com.apple.iTunes" to playpause
end playpause
end script
In an Objective-C method, both:
- (void)callASOC
{
iTunesControllerInstance = [NSClassFromString(#"iTunesController") new];
[iTunesControllerInstance playpause];
[iTunesControllerInstance release];
}
and
- (void)callASOC
{
[NSClassFromString(#"iTunesController") playpause];
}
will call the playpause handler in the AppleScriptObjC file. The latter formulation will generate a warning a compile time, but works.
I was not able to find any documentation confirming or refuting this.
Thanks to #Friziab who reminded me of the NSClassFromString
So I could call a AppleScriptObjC method in my AppDelegate.applescript from another class (script) (NSView subclass)
I don't use AppleScriptObjC so there may be a proper way of doing it but this worked
current application's NSClassFromString("AppDelegate")'s popWindow()