Bean scope is generating java.lang.UnsatisfiedLinkError - spring

I have multi module maven project,which has one common module which is being used by other modules. In common module I have few beans(Beans are having singleton scope) that are used by other modules application context. Now the problem is having after using those beans in one module(m1) which was not previously using these beans. Importing the common.xml(Beans are defined here) in Application context of module(m1) generates lot of issue(Cannot find the beans). So I decided to directly use those beans in application context of module(m1). If I keep the scope of beans to singelton , I get java.lang.UnsatisfiedLinkError: no jzmq in java.library.path. This issue is solved by using prototype as scope.
Any idea about this issue.

1 Using native methods make your Java application code platform dependent.
2 The System.loadLibrary method is equivalent as executing the Runtime.getRuntime().loadLibrary method.
3 The System.loadLibrary method shall be used in a static initializer block, in order to be loaded only once, when the JVM loads the class for the first time.

Related

Spring-Boot: share an object between components

I have a custom object which I like to share between different Spring-Boot components (e.g. WebHandler, Authenticator, Filter).
Maybe the easiest way is a static object in the main-class but thats not very elegant.
Whats the most common way to do it?
The whole point of spring as a container is to manage your objects.
Now statics do not have a well defined lifecycle ( when exactly this object gets created, who disposes it when the application gets closed, etc)
Speing answers all these questions by using thecdependency injection techniques. If you're already using spring then you should define this 'shared object' as a spring bean (by default it will have scope singleton just like static object that you've proposed but managed by spring container which is better - it will manage the lifecycle of the object by itself)
Then given the classes that must be dependent of the object are beans by themselves you can inject that bean:
class MySharedObject {}
class MyWebHandler implementsWebHandler {
private final MySharedObject mySharedObject;
public MyWebHandler(MySharedObject mySharedObject) {
this.mySharedObject = mySharedObject;
In addition to the lifecycle management this way allows easy unit testing of classes that use the shared object (like 'MyWebHandler' in this case) - now uou can create a stub/mock of the shared object and pass it into the handler - something that cannot really be easily done when using statics
So in summary if you can use spring and define it as a bean - by all means do so, the usage of statics is discouraged if you already have a dependency injection container
If you have shared object first of all it should not contain any state as differents components can change it and also it should be thread safe.
It is fine to reuse it across all components via #Autowired annotation but you need to be sure that it is threadsafe. Spring bean scope singleton is not thread safe out of box it dependes how you write the code.
You can use as static method but it dependes on logic which you have and if those component has an dependency on another objects and if they need to in spring IOC.

Global application context/environment runtime properties

There are some properties which are not read from a configuration file but are acquired from some remote resources and are constant, for example, user ID from a database. They are global in app context (it means that each application context has same properties with different values).
I expected something like context.setProperty or context.setGlobalProperty or context.getEnvironment().setProperty, but I couldn't find such methods.
My current solution is to create a singleton lazy bean which is initialized during application initialization and then it can be autowired into any bean. But it seems to me that this is not the best method.
It's not a good idea to change environment during runtime.
Environment is also bean in context, so your solution is ok.
Also you can use static container with dynamic variables and fill it during runtime

Application context getting initialized twice

I'm new to Spring and have inherited some Groovy code that relies heavily on Spring. I'm now trying to figure out why my application context is getting intialized twice, and causing multiple copies of my beans to be created.
I've added a #Scheduled task that gets executed with a ThreadPoolTaskExecutor, and inside the task I'm using the application context's getBean static method. In the main program, I'm also using the context to get beans, and I'm finding that the context is getting initialized in both the main program and the scheduled task, which means the task is using a different copy of the bean than the rest of the program.
Ugh, never mind. I was creating two different ApplicationContext objects, both loading the same Config. So problem solved.

Does ComponentScan order matter?

I'm setting up a very small Spring/REST/JPA project with Boot, using annotations.
I'm getting some Bean not found errors in my REST controller class that has an Autowired repository variable, when I move my JPA repository class out to a different package, and calling componentscan on its package. However, everything was working fine when all my files(5 total) were in the same package.
So I was wondering, however unlikely, if the component scan order matters? For example, if a class is AutoWiring some beans from a package that has not been 'component scanned' yet, will that cause a Bean not found error?
No, Spring loads all configuration information, from files and annotations and the environment when appropriate. It then creates beans (instances of classes) according to a dependency tree that it calculates in memory. In order to do this it has to have a good idea of the entire configuration at startup. The whole model derived from all the aggregated configuration information is called the Application Context.
In modern versions of spring the application context is flexible at runtime and so it's not quite the case that all the configuration is necessarily known up front, but the configuration that is flexible is limited in scope and must be planned for carefully.
Maybe you need to share some code. When you move that stuff, you also need to tell Spring where they went. My guess would be you haven't defined #EntityScan and #EnableJpaRepositories (which default to the location of #EnableAutoConfiguration).
There could be several problems:
You moved your class out of the some package where you have #ComponentScan without arguments. That basically means that components are scan only in this package and its children. Thus, moved class are not scanned and there is no bean to wire.
Wrong package name in #ComponentScan args.
The order isn't matter at all. There is an #Order annotation, but it's purpose is more about loading multiple implementations of sth in a different order.
At first Bean Definitions are created and they have nothing to do with wiring. Then via bean post processors, autowired beans are injected. Since there were no bean definition. There is nothing to inject.
In a well structured program it doesn't, because first each bean gets instantiated, then autowired and then you can actually use them.
However there could be situations where the order does matter and I had an issue figuring out what was going on. So this is an example where it would matter:
You have some Repository that you want to fill with data initially, call it SetupData component.
Then you use #PostConstruct to save the default objects.
You have some component that this Repository depends on but isn't managed by Spring, for example a #Converter.
And that #Converter depends on some other component which you would statically inject.
In this case #PostConstruct methods will be executed before the components into your #Converter get autowired which will result in an exception.
Relying on ComponentScan order is a bad habit, because it's not intuitive especially when you are working with multiple people who may not know about. Or there might be such dependencies that you can't fix the code by changing the scan order.
The best solution in this case was using a task executor service that takes care of running initialization functions.

Calling remote EJB3 without interface classes available

When calling remote EJB3 (Glassfish) from another EJB module, it is usual to have interfaces available, they are included as JAR file so that when you do JNDI lookup everything works as expected.
I have a situation where EJB3 JNDI name is determined at runtime, and my attempts to access the EJBs retrieved from JNDI in usual way fail, container complains ClassNotFound for remote interface classes. This is odd to me, since all the interface classes extend a parent interface for which I DO have a dependency in my calling EJB module, i.e.:
IParent ejbRef = (IParent) JndiLocator.getObject("jndinameRemote");
Is this possible with EJB3, without the need to have an exact remote EJB interface bytecode available in my JAR?
Bozo
Even though i am exactly not sure what the above setup is , I had a similar need of trying to invoke EJB when the client jars are not known during the compile time, infact in addition there is also no way for me to know what Application service is the EJB deployed at.
I had managed to do this by writing my Customized Class Loader , the catch here is that the Class which in turn tries to invoke the EJB must be itself loaded using the Customized class loader along with all the necessary jars i.e client jar with interfaces and models and the application server specific client jar.
I passed all the context properties as an input to my Invoker class to initialize context factory and invoke the bean.
These are high level steps to achieve this
Create Class EJBInvoker with method invokeEJB, you can pass it couple of Maps with properties for preparing context and Ejb interface , method , parameters classes , values and output class.
Use reflection to create instance of InitialContextFactory as well as Bean object , parameters and method invokation.
Add the above class to separate jar file and invoke the method with properties required from external project using a customized class loader.

Resources