lambda expression prevents class from spring component-scan - java

Our Application have Class Test with #Component annotation.
Lambda expression is being used here.
#Component
public class Test{
private ScheduledExecutorService schedulerExecutorService;
private long timeoutForRollBack=180000;
private long timeoutFailoverDelay=180000;
public static Test getInstance() {
if (INSTANCE == null) {
/*Actual instance will be created via reflection. using new for understanding */
INSTANCE = new Test();
}
return INSTANCE;
}
public void handleFailOver(){
schedulerExecutorService.scheduleWithFixedDelay(
() -> {
schedulerExecutorService.shutdown();
},
timeoutForRollBack, timeoutFailoverDelay, TimeUnit.MILLISECONDS);
}
}
But this Test class bean is not created. But when this method is commented, then the Test class bean is created.
Using Java 8 oracle and Eclipse Neon2.
Suggest if any changes needed to fix this.
Edit 1:
Found similar issue reported:
https://java.net/jira/browse/JAVASERVERFACES-3732
Edit 2:
Similar issue faced https://github.com/orfjackal/retrolambda/issues/121
P.S:
if
() -> {
schedulerExecutorService.shutdown();
}
is replaced with private innerclass, this is working fine.
private class TerminalScheduledExecutor implements Runnable{
#Override
public void run() {
schedulerExecutorService.shutdown();
}
}.
However looking forward for solutions without replacing lambda functions.

Have you tried to change spring framework's logging level for detailed bean creation logs?
per suggestion here: Question with no answers, but issue solved in the comments (or extended in chat)

Found the solution at last:
Issue was with
org.reflections.Reflections
version. Upgraded it to
0.9.9-RC2
and the issue is resolved.
As per #OnurAktaş suggestions, enabled debug and found that
could not scan file error occurred in org.reflections.reflection.

Related

Unable to call function of autowired class

I have the following classes :
Class 1:
package com.assets;
#Component
#Scope("request)
public class AssetDetailsImpl implements AssetApi
{
public void function1(){
....
}
public void function2(){
AssetUtil.test1();
}
}
Class 2:
package com.assets;
#Component
public class AssetUtil
{
#Autowired
AssetDetailsImpl impl;
//some functions
public static void test1{
impl.function1();// NPE I am getting
}
Here my auto wiring not working, its coming null. Both the classes are in the same package. Is it because of the request scope which is there in AssetDetailsImpl? I even tried with #Inject that also was not working. Can anyone please help me to resolve this? Thanks in advance!
I have tried removing the scope, but then also the same problem.
I have also tried:
AssetUtil(AssetDetailsImpl impl) {
this.impl = impl;
}
But I am not sure how to deal with the static thing then also how to invoke this constructor?
The method test1 is static.
But Spring doesn't work with static members because it creates instances of the beans.
Remove static:
public void test1{
impl.function1();
}
And now you have to make sure that the client of this method is also using autowiring to get an instance of AssetUtil
It looks to me like the issue is that the AssetDetailsImpl Component is Request-scoped, which means it comes and goes with each HTTP request, while the AssetUtil Component which is trying to use it is default-scoped, which is Application/singleton scope.
Personally, I try to use singletons as much as possible. I wouldn't use request scope for the first Component.

Do Spring beans that depend on other beans get singleton versions of those beans by default?

I am new to using the Spring-Framework, and I am actually using the spring-boot library. I have the following question:
I understand that beans registered in the #Configuration class with #Bean are singleton by default, however I am finding that beans that rely on other beans are getting their own instances of those beans, not the singleton instance I would like them to have.
For example:
#Bean
public static void myFirstService() {
return new MyFirstService(foo(), bar());
}
#Bean
public static void mySecondService() {
return new MySecondService(foo(), bar());
}
#Bean
public static void foo() {
return new Foo();
}
#Bean
public static void bar() {
return new Bar();
}
I would like the instances of MyFirstService and MySecondService to have the same instances of foo and bar. That is what should be happening by default, right? Or am I misunderstanding something completely with how beans are handled?
I have played around with the #Scope annotation (to no avail), but it is my understanding I shouldn't have to.
Thanks in advance for any input! :)
No sooner had I posted this, I realised the problem... (always the way...)
I figured out the answer. Just in case anyone else made the same mistake. My IDE corrected the methods to be "static", which of course they should not be.
I have changed these methods to instance methods, and everything worked as expected.
You should have used #Autowired here as follows:
#Autowired
private MyFirstService myFirstService;
#Autowired
private MySecondService mySecondService;
And in java class code for MyFirstService and MySecondService, auto wire the foo and bar also.

Guice custom scope entry and exit in Java console application

I'm currently trying to implement injection in a Java console application using Guice. The application imports XML files in a database. Every import operation is done in an AbstractImporter, which can either be a UserImporter, a ScheduleImporter, etc.
public class ScheduleMigrator extends AbstractMigrator {
private final UserImporter userImporter;
private final ScheduleImporterFactory scheduleImporterFactory;
#Inject
public ScheduleMigrator(UserImporter userImporter,
ScheduleImporterFactory scheduleImporterFactory) {
this.userImporter = userImporter;
this.scheduleImporterFactory = scheduleImporterFactory;
}
public void migrate() {
// Migrate users
userImporter.run();
// Migrate schedules for each type
for (ScheduleType scheduleTypes : ScheduleType.values()) {
ScheduleImporter importer =
scheduleImporterFactory.create(scheduleTypes);
importer.run();
}
}
}
public class UserImporter extends AbstractImporter {
private final UserTransformer userTransformer;
private final ConfigurationService configurationService;
#Inject
public UserImporter(UserTransformer userTransformer,
ConfigurationService configurationService) {
this.userTransformer = userTransformer;
this.configurationService = configurationService;
}
public void run() {
// do stuff here
}
}
#Singleton
public class UserTransformer {
// ...code ommited...
}
#ImporterScoped
public class ConfigurationService {
// ...code ommited...
}
I have successfully created my own scope (#ImporterScoped) for classes that should only be available and instantiated only in an Importer. The scope was created by following the steps in the wiki. My problem is, how should I enter and exit the scope in ScheduleMigrator?
As you can see in ScheduleMigrator, each Importer is injected and its run() method is invoked. There are also factories (based on Guice's #AssistedInject feature). This is where I want each scope to start and end, UserImporter and ScheduleImporterFactory should run in their own scope.
This is a rough idea of what I'm trying to achieve:
importerScope.enter();
(new UserImporter()).run();
importerScope.exit();
Guice's documentation mentions the use of interceptors, but I'm a little lost on how it can be implemented.
Using AOP seems a very over-engineered approach and might introduce problems. When do I enter the scope? When do I exit? What happens if I instantiate two Importer objects?
Instead, I added a runScoped method in AbstractMigrator that takes a Runnable and executes it. Using injection I get the ImporterScope scope, enter and exit it appropriately.
protected void runScoped(Runnable function)
{
scenarioScope.enter();
try {
function.run();
}
finally {
scenarioScope.exit();
}
}
Usage:
runScoped(() -> {
ScheduleImporter importer =
scheduleImporterFactory.create(scheduleTypes);
importer.run();
});
This introduces one problem though. In ScheduleMigrator, I can't have Importers injected, because their instantiation would occur outside of a scope and Guice throws an OutOfScopeException. I had to wrap each Importer in a Provider.
private final Provider<UserImporter> userImporterProvider;
runScoped(() -> {
UserImporter importer = userImporterProvider.get();
importer.run();
});

Initializing with #BeforeClass vs eager initialization in java

I am using spring with dependency injection and came across this puzzling piece of code in my TestNG class and want to clear my head around this issue
I have this below code
public class myBase {
#Autowired #Lazy #Qualifier("someInstanceA")
protected SomeClass someInstanceA;
.
.
}
public class myTestB extends myBase {
private String varB = someInstanceA.getVarB();
#Test
.
.
}
This above code gave me a NullPointerException at line
private String varB = someInstanceA.getVarB();
But when I do this below
public class myTestB extends myBase {
private String varB;
#BeforeClass
private void getVarB() {
varB = someInstanceA.getVarB();
}
#Test
.
.
}
The tests ran fine. I read that BeforeClass is like a default constructor and eager initialization is similar to initializing a variable using a default constructor. What am I missing here?
Short answer : Bean injection happens after creation of instances of your class.
Since in the creation of myTestB (which should start with an uppercase, by the way), you call getVarB on someInstanceA which is not yet injected, you get a NullPointerException.
The second case works because #BeforeClass run one time before first test run, after object creation. Thus when calling someInstanceA#getVarB in getVarB method, someInstanceA is already autowired and not null.

CDI #Inject Instance #Any - But instance never populated with instances

Why does 'instance' never iterate over any implementations? What am I missing?
JBoss EAP 6.3.0.GA (AS 7.4.0.Final-redhat-19)
public interface Simple { }
public class SimpleA implements Simple { public SimpleA() { } }
public class SimpleB implements Simple { public SimpleB() { } }
public class SimpleUser {
#Inject #Any Instance<Simple> instance;
#PostConstruct public void init() {
for (final Simple simple : instance) {
System.out.println(simple);
}
}
}
In case it helps someone else, I also am using Deltaspike 1.5.2 and am running into the same issue (if I remove Deltaspike, I no longer have the problem).
In my case adding producer methods did not solve it. After looking around I BeanProvider which gets around the problem but is far from elegant.
https://deltaspike.apache.org/documentation/core.html#BeanProvider
I had to call
List<MyServiceInterface> myServiceList = BeanProvider.getContextualReferences(MyServiceInterface.class, false, false);
There are probably better ways. I notice Deltaspike turns on a bunch of extensions by default, but couldn't find docs on how to disable the ones I am not using as I suspect one may be causing this issue.

Categories

Resources