How to create multiple RestConnector objects for Multithreading in spring boot

What product/components do you use and which version/fix level are you on?

Cumulocity iot

Is your question related to the free trial, or to a production (customer) instance

dev tenant used for development

What are you trying to achieve? Please describe it in detail.

Trying to create multiple RestConnector objects (atleast 10-30) for a Multithreaded Class in a loop. But not able to create multiple instances of RestConnector. Please let me know the way to achieve this. In non-thread code inside the @Service class for a single POST methods using RestConnector it is working. But whenever I use RestConnector as @AutoWired inside my Runnable implemented thread logic class, it says RestConnector is null.

Do you get any error messages? Please provide a full error message screenshot and log file.

Have you installed all the latest fixes for the products and systems you are using?

Hi Sethu,

why do you require multiple RestConnector “objects”?
Within a Runnable you @Autowired might not work as you expect. A code example would be helpful.
Usually you would need to pass the RestConnector bean into your Runnable, as you cannot inject it with the @Autowired annotation, AFAIK, hence it is null.

Regards Kai

also the Java SDK itself only uses a single instance of RestConnector. So you should be good to reuse them in multiple threads. If you decide that you need multiple instances, make sure to not create them per-request They use this class internally:
https://docs.oracle.com/javaee/7/api/javax/ws/rs/client/Client.html

which is expensive to instantiate.

Thanks Kai for responding. I tried to pass the RestConnector to my Runnable Class. Its not working. But I will try again.

Thanks Harald for the reply. Yes that was my ideas to instantiate RestConnector per thread. But that didnt work by AutoWired. I will try to reuse RestConnector by passing the instance created by @Autowired once in my Runnable class. I will seek your help if needed again. Thanks.

Hi Kai,

Below are the snippets from the code. Kindly have a look at this.

Service Class code

@Service
public class RestClientServiceImpl3B {

@Autowired
public RestConnector restConnector1;

/* Concurrency starts here */
LOGGER.info("Before Threading ");
for (int icounter = 0; icounter < 2; icounter++) {
	RunnableWorker r = new RunnableWorker(restConnector1);
	Thread t1 = new Thread(r);
	t1.start();
}

LOGGER.info("After Threading ");

/* Concurrency ends here */

Runnable Class code

public class RunnableWorker implements Runnable {

private	RestConnector restConnector1;

public RunnableWorker(RestConnector restConnector1) {
	this.restConnector1 = restConnector1;
}

private static final Logger LOGGER = LoggerFactory.getLogger(RunnableWorker.class);

@Override
public void run() {
	
	String path = "https://cloud.iot.solenis.com/service/unify/measurement/measurements?dateFrom=2022-08-01T00:00:00.00Z&dateTo=2022-08-01T23:59:59.00Z&valueFragmentType=sol_onguardMeasurement&source=1437&pageSize=50000";
			
	long startDateCheck = System.currentTimeMillis();
	
	MeasurementCollectionRepresentation collectionRep = restConnector1.get(path,CumulocityMediaType.APPLICATION_JSON_TYPE, MeasurementCollectionRepresentation.class);

	long endDateCheck = System.currentTimeMillis();
	LOGGER.info("Time taken - check..check..check.. "+(endDateCheck-startDateCheck));
	
}

}

Error thrown is

Exception in thread “Thread-1” org.springframework.beans.factory.support.ScopeNotActiveException: Error creating bean with name ‘scopedTarget.tenantRestConnector’: Scope ‘tenant’ is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: Not within any context!

Hi Sethu,
the java.lang.IllegalStateException: Not within any context! exception clearly shows you that the new thread is not within any context.
Hence the RestController bean is there and ready, however no tenant-information/context is known.

This requires to pass the related tenant into the runnable as well and use the MicroserviceSubscriptionService (runForTenant or callForTenant methods) to get into the context again within the runnable (new thread).

Regards Kai

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.