Get Resource from ClassLoader with leading slash - resources

i'm trying to access an external method of third part jar by reflection.
1) i add external jar to classpath by "addUrl" method of system class loader
2) i retrieve class type, method, then i invoke the method and it's all working
I decompile part of external jar:
public class Deploy
{
...
public static Deploy init()
{
InputStream i = Deploy.class
.getClassLoader()
.getResourceAsStream(
"/com/example/props");
}
}
Using the third part component this call works, because it reads correctly "props" file.
But in my code it returns null, intead of:
"/com/example/props"
i've tried:
"com/example/props"
without slash and it works.
How can i do to have that code working in my application? Any workaroud? (i have to call it through reflection)
Thanks

If you are assuming the JVM class loader is a URLClassLoader, then be aware that the JDK does not guarantee this, and it will likely not be true as of Java 9 (JEP 261).
URLClassLoader.getResourceAsStream should not be passed a leading "/", so that is likely a bug in the third party JAR. Your best option is to load the third party JAR in a custom ClassLoader (e.g., your own subclass of URLClassLoader) that can handle that leading "/" (e.g., override getResourceAsStream, remove the "/", and delegate to URLClassLoader).

Related

Custom addon component not found

I'm trying to create a component within an addon. Everything works fine during impex process (contentslot, pagetemplate etc.) but it doesn't get rendered when accessing the page.
I've followed these steps but my controller isn't even get called.
#Controller("ConfirmationComponentController")
#RequestMapping(value = ControllerConstants.Actions.Cms.ConfirmationComponent)
public class ConfirmationComponentController extends AbstractCMSAddOnComponentController<ConfirmationComponentModel> {
#Override
protected void fillModel(HttpServletRequest request, Model model, ConfirmationComponentModel component) {
}
}
I've added the component's jsp in "WEB-INF/views/responsive/cms/.." from the addon module but I keep getting this error:
File [/WEB-INF/views/addons/trainingcore/responsive/cms/confirmationcomponent.jsp] not found
P.S.: I've managed to get the component controller to be called, but the getView() is returning a wrong path and that's why the component is not getting called. Any help? Thank you very much:)
Should this component to be created in addon *-items.xml?
What you need to know first
Using addons is a complicated endeavor in hybris. You need to know, that the resources are not used in the addon, but they are copied (during build process) to your storefront, where they are used.
All classes in
myaddon/acceleratoraddon/web/src/
will be copied to:
mystorefront/web/addonsrc/myaddon/
All resources in
myaddon/acceleratoraddon/web/webroot/
will be copied to corresponding folders:
mystorefront/web/webroot/WEB-INF/_ui-src/addons/myaddon
mystorefront/web/webroot/WEB-INF/tld/addons/myaddon
mystorefront/web/webroot/WEB-INF/messages/addons/myaddon
mystorefront/web/webroot/WEB-INF/tags/addons/myaddon
mystorefront/web/webroot/WEB-INF/views/addons/myaddon
That means
That means, that the effective path to your component jsp will not be something like:
/WEB-INF/views/cms/...
but will be something like:
/WEB-INF/views/myaddon/cms/...
The path myaddon will depend on the extension your component is declared in. So if you declare it in trainingcore-items.xml it will be
/WEB-INF/views/trainingcore/...
If you declare it in myaddon-items.xml it will be
/WEB-INF/views/myaddon/...

mockito - mock protected method in different packages

I am writing the test case using mockito for a protected method.
public HttpResponse createPostRequest(HashMap<String, String> requestHeaders, String url, String methodName)
{
//some logic
}
my class is in src/main/java and test case is in different package src/main/test.
and am using the following.
Mockito.doReturn(mockHttpResponse).when(userServiceImpl).createPostRequest(Mockito.any(HashMap.class),
Mockito.any(String.class),Mockito.any(String.class));
but it is not working. It is asking to change the method signature to public.
Please help on that.
Thanks.
This seems a configuration problem with your project structure. Your main class is in src/main/java and test class is in src/main/test with one source folder src.
While you could get this to work (setting source folders in buildpath etc.), but most of the time below project structure is used (eg. in spring boot/ maven):
Project-Name
bin
lib
src
main
java
SomeMainClass.java
resources
test
java
TestSomeMainClass.java
resources
This structure has two source folders, one for main (src/main/java) and other one for test (src/test/java). This has the advantage that TestSomeMainClass can access the package private i.e. default member fields of SomeMainClass.
The project structure is src/main/java and src/test/java. but with default modifier not able to mock the method. It is asking to modify the modifier as public

Ways of loading external dll and injecting conditionally multiple implementations using autofac

i have an interface called say IMyHook which has some implementation in an external project(dll). i use this interface in my businesslogic classes and on my application startup i inject external implementation of this interface using Autofac.
my interface
public interface IMyHook {
public void MyHookMethod();
}
my business logic class
public class myBusinessLogic{
// implementation injected by autofac
public IMyHook Hook {set;get;}
public void MyBusinessLogicMethod (flag){
if(Hook !=null){
Hook.MyHookMethod();
}
else{
// other code
}
}
}
auto face properties injection
var hoodAssemblyPath = "C:\\hook.dll";
builder.RegisterAssemblyTypes(hoodAssemblyPath).
AsImplementedInterfaces().PropertiesAutowired();
this works all fine but now issue is that my external dll (hook.dll) can have more then one implementations of IMyHook. And i want to decide which implementation to load in my MyBusinessLogicMethod method using the input paramameter flag. e.g
if (flag ==1)
then load implementation 1
else if (flag == 2)
then load implememtation 2
etc
i can do this using Reflections (and a custom attribute in my external classes representing each value of flag) by loading assembly and then the appropriate class using custom attribute on it.
But my question is;
is this the right way loading external dll on each method call using reflection etc or are there any other ways of doing this? using autofac or anything else?
with all this i want to let users of my application to inject their code in my application for some of the functionality. so external dll or implementations will basically be written by my users and then my application will just load and execute the methods.
Registering all the dependencies using AsImplementedInterfaces().PropertiesAutowired(); could be quite heavy and you may encounter problem on complex scenario. Furthermore, you won't be able to customize the way the registration is made for each registration (controlling lifetimescope, etc.)
I would recommend to register module that your users have to write inside these assemblies. Then load them using RegisterAssemblyModules.
if (flag ==1) then load implementation 1 else if (flag == 2) then load implememtation 2 etc
How would you decide which implementation to use ? implementation1 means implementation coming from Hook1.dll ?
A common way to do this is to use Named and Keyed Services and/or Component Metadata
If you can't ask your users to implement module you can use something like this :
builder.RegisterAssemblyTypes(hoodAssemblyPath)
.AsImplementedInterfaces()
.PropertiesAutowired()
.WithMetadata("source", "hook1");
and then
IFoo foo = container.Resolve<IEnumerable<Lazy<IFoo, String>>>()
.First(f => f.Metadata["source"] == "hook1")
.Value
If you do it this way consider using typed metadata.

Add constraints to properties of Groovy class (not Grails domain class!)

How can we add some common constraints (i.e. maxLength, nullable) to a property of a Groovy class? I know we can do it at Grails domain class, but is it possible if that is a Groovy class (I use it as a DTO class for my Grails project)?
Thank you so much!
You can add constraints to command classes. If a command class is in the same .groovy file as a controller (in Groovy you can have more than one public class in each .groovy file), you don't need to do anything special for Grails to recongise it as a command class.
However, if your command class is somewhere else (e.g. under src/groovy), you need to annotate it with #Validateable and add the package name to the grails.validateable.packages parameter in Config.groovy. Here's an example of a command that's not in the same file as a controller
pacakge com.example.command
#Validateable
class Person {
Integer age
String name
static constraints = {
name(blank: false)
age(size 0..100)
}
}
Add the following to Config.groovy
grails.validateable.packages = ['com.example.command']
Command classes have a validate() method added by Grails. After this method is called, any errors will be available in the errors property (as per domain classes).
Using a grails Command Object is probably your best bet. It has constraints and validation, but no database backing. It's normally a value object that controllers use, but you could instantiate one outside of a controller without any problems.
Not sure if this is relevant to your use (I am not familiar with DTOs), but in the current version (2.3.8), you can also add Grails constraints to an abstract class, and they will be inherited by the domains that extend it. Your IDE might not like it though ;)

NInject and thread-safety

I am having problems with the following class in a multi-threaded environment:
public class Foo
{
[Inject]
public IBar InjectedBar { get; set; }
public bool NonInjectedProp { get; set; }
public void DoSomething()
{
/* The following line is causing a null-reference exception */
InjectedBar.DoSomething();
}
public Foo(bool nonInjectedProp)
{
/* This line should inject the InjectedBar property */
KernelContainer.Inject(this);
NonInjectedProp = nonInjectedProp;
}
}
This is a legacy class which is why I am using property rather than constructor injection.
Sometime when the DoSomething() is called the InjectedBar property is null. In a single-threaded application, everything runs fine.
How can this be occuring and how can I prevent it?
I am using NInject 2.0 without any extensions, although I have copied the KernelContainer from the NInject.Web project.
I have noticed a similar problem occurring in my web services. This problem is extremely intermittent and difficult to replicate.
First of all, let me say that this is wrong on so many levels; the KernelContainer was an infrastructure class kept specifically to work around certain limitations in the ASP.NET WebForms page lifecycle. It was never meant to be used in application code. Using the Ninject kernel (or any DI container) as a service locator is an anti-pattern.
That being said, Ninject itself is definitely thread-safe because it's used to service parallel requests in ASP.NET all the time. Wherever this NullReferenceException is coming from, it's got little if anything to do with Ninject.
I can think of two possibilities:
You have to initialize KernelContainer.Kernel somewhere, and that code might have a race condition. If something tries to use the KernelContainer before the kernel is fully initialized (possible if you use the IKernel.Bind methods instead of loading modules as per the guidance), you'll get errors like this. Or:
It's your IBar implementation itself that has problems, and the NullReferenceException is happening somewhere inside the DoSomething method. You don't actually specify that InjectedBar is null when you get the exception, so that's a legitimate possibility here.
Just to narrow the field of possibilities, I'd eliminate the KernelContainer first. If you absolutely must use Ninject as a service locator due to a poorly-designed legacy architecture, then at least allow it to create the dependencies instead of relying on Inject(this). That is to say, whichever class or classes need to create your Foo, have that class call kernel.Get<Foo>(), and set up your kernel to Bind<Foo>().ToSelf().

Resources