Accessing a request scoped bean in a different thread (that handles websocket traffic)












0














I am having issues accessing a bean that is defined with a request centric scope in a thread that is not the request's thread.



My scenario is as follows:




  1. Execution starts from a REST request coming from a client. In this request I define a bean that allows me to access data in a DB. The location of the DB depends on the user performing the request itself, hence why the bean with which the db is accessed is bound to the request itself. I get the user details from the request's auth and use them to init the bean.


  2. During the HTTP request the code may call to an external service over a websocket connection. The ws traffic is handled by different StompFrameHandler classes. When these handle traffic they do so on a dedicated thread, which is not the same as the initial http request (and rightfully so!).


  3. Some of these StompFrameHandler classes need to access the DB relevant to the user in context for the current (REST) request.


At 3 is where I encounter the issue:



No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.



I understand what the error is telling me and the fact that due to how I have defined my bean (request scope bound) spring does not allow me to access it in other threads. However I still need to use that db accessing bean from the ws traffic handling thread.



Here is a simplified version of my code:



The bean configuration:



@Configuration
public class DbClientRequestScopeConfiguration {

private DbClientFactoryI dbClientFactory;
private AuthenticationFacadeI authenticatedUserInfo;

@Autowired
public DbClientRequestScopeConfiguration(DbClientFactoryI dbClientFactory, AuthenticationFacadeI authenticatedUserInfo) {
this.dbClientFactory = dbClientFactory;
this.authenticatedUserInfo = authenticatedUserInfo;
}

@Bean
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public DbClientI getDbClient() {

Authentication auth = authenticatedUserInfo.getAuthentication();

return dbClientFactory.getDbClient(auth.getDetails());
}
}


The DataService using the bean (this runs in the request's thread)



@Service
public class DataService {

private DbClientI dbClient;

@Autowired
public DataService(DbClientI dbClient) {

this.dbClient = dbClient;
}

...
}


The frame handler working with the WS traffic Note that this in not initialised by Spring's context, instead it is manually initialised by a class running in the request's thread, which gives it the instance of the @DataService coming from the Context.



public class SaveDataFrameHandler implements StompFrameHandler{

private DataService dataService;

public SaveDataFrameHandler(DataService dataService) {
this.dataService = dataService;
}

@Override
public Type getPayloadType(StompHeaders headers) {
return JsonNode.class;
}

@Override
public void handleFrame(StompHeaders headers, Object payload) {
// This method will be called on a separate thread
JsonNode jsonPayload = (JsonNode) payload;
dataService.saveRecord(jsonPayload);
}
}


I am looking for suggestions on how I could actually use that bean in my ws thread or how to rearchitect the solution so that I do not run into this problem.



Thanks in advance!



UPDATE:



I have managed to get around the problem for now even though I am not 100% happy with the solution. To avoid repetition, I posted my current solution in a new question, since I am facing a different issue now still related to this code:
Proxied prototype bean is created every time a method is invoked from it










share|improve this question
























  • Please provide the relevant part of your code. Add a Minimal, Complete, and Verifiable example including proper example input/output data.
    – Bsquare
    Nov 23 '18 at 10:23










  • Hi, sure thing! I just edited my post to add the code. Cheers.
    – edoDev
    Nov 23 '18 at 11:49
















0














I am having issues accessing a bean that is defined with a request centric scope in a thread that is not the request's thread.



My scenario is as follows:




  1. Execution starts from a REST request coming from a client. In this request I define a bean that allows me to access data in a DB. The location of the DB depends on the user performing the request itself, hence why the bean with which the db is accessed is bound to the request itself. I get the user details from the request's auth and use them to init the bean.


  2. During the HTTP request the code may call to an external service over a websocket connection. The ws traffic is handled by different StompFrameHandler classes. When these handle traffic they do so on a dedicated thread, which is not the same as the initial http request (and rightfully so!).


  3. Some of these StompFrameHandler classes need to access the DB relevant to the user in context for the current (REST) request.


At 3 is where I encounter the issue:



No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.



I understand what the error is telling me and the fact that due to how I have defined my bean (request scope bound) spring does not allow me to access it in other threads. However I still need to use that db accessing bean from the ws traffic handling thread.



Here is a simplified version of my code:



The bean configuration:



@Configuration
public class DbClientRequestScopeConfiguration {

private DbClientFactoryI dbClientFactory;
private AuthenticationFacadeI authenticatedUserInfo;

@Autowired
public DbClientRequestScopeConfiguration(DbClientFactoryI dbClientFactory, AuthenticationFacadeI authenticatedUserInfo) {
this.dbClientFactory = dbClientFactory;
this.authenticatedUserInfo = authenticatedUserInfo;
}

@Bean
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public DbClientI getDbClient() {

Authentication auth = authenticatedUserInfo.getAuthentication();

return dbClientFactory.getDbClient(auth.getDetails());
}
}


The DataService using the bean (this runs in the request's thread)



@Service
public class DataService {

private DbClientI dbClient;

@Autowired
public DataService(DbClientI dbClient) {

this.dbClient = dbClient;
}

...
}


The frame handler working with the WS traffic Note that this in not initialised by Spring's context, instead it is manually initialised by a class running in the request's thread, which gives it the instance of the @DataService coming from the Context.



public class SaveDataFrameHandler implements StompFrameHandler{

private DataService dataService;

public SaveDataFrameHandler(DataService dataService) {
this.dataService = dataService;
}

@Override
public Type getPayloadType(StompHeaders headers) {
return JsonNode.class;
}

@Override
public void handleFrame(StompHeaders headers, Object payload) {
// This method will be called on a separate thread
JsonNode jsonPayload = (JsonNode) payload;
dataService.saveRecord(jsonPayload);
}
}


I am looking for suggestions on how I could actually use that bean in my ws thread or how to rearchitect the solution so that I do not run into this problem.



Thanks in advance!



UPDATE:



I have managed to get around the problem for now even though I am not 100% happy with the solution. To avoid repetition, I posted my current solution in a new question, since I am facing a different issue now still related to this code:
Proxied prototype bean is created every time a method is invoked from it










share|improve this question
























  • Please provide the relevant part of your code. Add a Minimal, Complete, and Verifiable example including proper example input/output data.
    – Bsquare
    Nov 23 '18 at 10:23










  • Hi, sure thing! I just edited my post to add the code. Cheers.
    – edoDev
    Nov 23 '18 at 11:49














0












0








0







I am having issues accessing a bean that is defined with a request centric scope in a thread that is not the request's thread.



My scenario is as follows:




  1. Execution starts from a REST request coming from a client. In this request I define a bean that allows me to access data in a DB. The location of the DB depends on the user performing the request itself, hence why the bean with which the db is accessed is bound to the request itself. I get the user details from the request's auth and use them to init the bean.


  2. During the HTTP request the code may call to an external service over a websocket connection. The ws traffic is handled by different StompFrameHandler classes. When these handle traffic they do so on a dedicated thread, which is not the same as the initial http request (and rightfully so!).


  3. Some of these StompFrameHandler classes need to access the DB relevant to the user in context for the current (REST) request.


At 3 is where I encounter the issue:



No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.



I understand what the error is telling me and the fact that due to how I have defined my bean (request scope bound) spring does not allow me to access it in other threads. However I still need to use that db accessing bean from the ws traffic handling thread.



Here is a simplified version of my code:



The bean configuration:



@Configuration
public class DbClientRequestScopeConfiguration {

private DbClientFactoryI dbClientFactory;
private AuthenticationFacadeI authenticatedUserInfo;

@Autowired
public DbClientRequestScopeConfiguration(DbClientFactoryI dbClientFactory, AuthenticationFacadeI authenticatedUserInfo) {
this.dbClientFactory = dbClientFactory;
this.authenticatedUserInfo = authenticatedUserInfo;
}

@Bean
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public DbClientI getDbClient() {

Authentication auth = authenticatedUserInfo.getAuthentication();

return dbClientFactory.getDbClient(auth.getDetails());
}
}


The DataService using the bean (this runs in the request's thread)



@Service
public class DataService {

private DbClientI dbClient;

@Autowired
public DataService(DbClientI dbClient) {

this.dbClient = dbClient;
}

...
}


The frame handler working with the WS traffic Note that this in not initialised by Spring's context, instead it is manually initialised by a class running in the request's thread, which gives it the instance of the @DataService coming from the Context.



public class SaveDataFrameHandler implements StompFrameHandler{

private DataService dataService;

public SaveDataFrameHandler(DataService dataService) {
this.dataService = dataService;
}

@Override
public Type getPayloadType(StompHeaders headers) {
return JsonNode.class;
}

@Override
public void handleFrame(StompHeaders headers, Object payload) {
// This method will be called on a separate thread
JsonNode jsonPayload = (JsonNode) payload;
dataService.saveRecord(jsonPayload);
}
}


I am looking for suggestions on how I could actually use that bean in my ws thread or how to rearchitect the solution so that I do not run into this problem.



Thanks in advance!



UPDATE:



I have managed to get around the problem for now even though I am not 100% happy with the solution. To avoid repetition, I posted my current solution in a new question, since I am facing a different issue now still related to this code:
Proxied prototype bean is created every time a method is invoked from it










share|improve this question















I am having issues accessing a bean that is defined with a request centric scope in a thread that is not the request's thread.



My scenario is as follows:




  1. Execution starts from a REST request coming from a client. In this request I define a bean that allows me to access data in a DB. The location of the DB depends on the user performing the request itself, hence why the bean with which the db is accessed is bound to the request itself. I get the user details from the request's auth and use them to init the bean.


  2. During the HTTP request the code may call to an external service over a websocket connection. The ws traffic is handled by different StompFrameHandler classes. When these handle traffic they do so on a dedicated thread, which is not the same as the initial http request (and rightfully so!).


  3. Some of these StompFrameHandler classes need to access the DB relevant to the user in context for the current (REST) request.


At 3 is where I encounter the issue:



No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.



I understand what the error is telling me and the fact that due to how I have defined my bean (request scope bound) spring does not allow me to access it in other threads. However I still need to use that db accessing bean from the ws traffic handling thread.



Here is a simplified version of my code:



The bean configuration:



@Configuration
public class DbClientRequestScopeConfiguration {

private DbClientFactoryI dbClientFactory;
private AuthenticationFacadeI authenticatedUserInfo;

@Autowired
public DbClientRequestScopeConfiguration(DbClientFactoryI dbClientFactory, AuthenticationFacadeI authenticatedUserInfo) {
this.dbClientFactory = dbClientFactory;
this.authenticatedUserInfo = authenticatedUserInfo;
}

@Bean
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public DbClientI getDbClient() {

Authentication auth = authenticatedUserInfo.getAuthentication();

return dbClientFactory.getDbClient(auth.getDetails());
}
}


The DataService using the bean (this runs in the request's thread)



@Service
public class DataService {

private DbClientI dbClient;

@Autowired
public DataService(DbClientI dbClient) {

this.dbClient = dbClient;
}

...
}


The frame handler working with the WS traffic Note that this in not initialised by Spring's context, instead it is manually initialised by a class running in the request's thread, which gives it the instance of the @DataService coming from the Context.



public class SaveDataFrameHandler implements StompFrameHandler{

private DataService dataService;

public SaveDataFrameHandler(DataService dataService) {
this.dataService = dataService;
}

@Override
public Type getPayloadType(StompHeaders headers) {
return JsonNode.class;
}

@Override
public void handleFrame(StompHeaders headers, Object payload) {
// This method will be called on a separate thread
JsonNode jsonPayload = (JsonNode) payload;
dataService.saveRecord(jsonPayload);
}
}


I am looking for suggestions on how I could actually use that bean in my ws thread or how to rearchitect the solution so that I do not run into this problem.



Thanks in advance!



UPDATE:



I have managed to get around the problem for now even though I am not 100% happy with the solution. To avoid repetition, I posted my current solution in a new question, since I am facing a different issue now still related to this code:
Proxied prototype bean is created every time a method is invoked from it







java multithreading spring-boot websocket stomp






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 7 '18 at 10:03







edoDev

















asked Nov 23 '18 at 9:52









edoDevedoDev

6518




6518












  • Please provide the relevant part of your code. Add a Minimal, Complete, and Verifiable example including proper example input/output data.
    – Bsquare
    Nov 23 '18 at 10:23










  • Hi, sure thing! I just edited my post to add the code. Cheers.
    – edoDev
    Nov 23 '18 at 11:49


















  • Please provide the relevant part of your code. Add a Minimal, Complete, and Verifiable example including proper example input/output data.
    – Bsquare
    Nov 23 '18 at 10:23










  • Hi, sure thing! I just edited my post to add the code. Cheers.
    – edoDev
    Nov 23 '18 at 11:49
















Please provide the relevant part of your code. Add a Minimal, Complete, and Verifiable example including proper example input/output data.
– Bsquare
Nov 23 '18 at 10:23




Please provide the relevant part of your code. Add a Minimal, Complete, and Verifiable example including proper example input/output data.
– Bsquare
Nov 23 '18 at 10:23












Hi, sure thing! I just edited my post to add the code. Cheers.
– edoDev
Nov 23 '18 at 11:49




Hi, sure thing! I just edited my post to add the code. Cheers.
– edoDev
Nov 23 '18 at 11:49












0






active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53444273%2faccessing-a-request-scoped-bean-in-a-different-thread-that-handles-websocket-tr%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53444273%2faccessing-a-request-scoped-bean-in-a-different-thread-that-handles-websocket-tr%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Berounka

Sphinx de Gizeh

Different font size/position of beamer's navigation symbols template's content depending on regular/plain...