Passing this in constructor
I came across some JMS calling code that initializes the JMS session inside of its constructor. The calling code implements the ExceptionListener interface and passes a reference to this to the connection factory object, as shown below:
public class JmsCode implements ExceptionListener {
private static final Logger logger = LoggerFactory.getLogger(JmsCode.class);
public JmsCode(String url, String username, String password, String trustStorePath, char trustStorePassword) throws JMSException {
ActiveMQSslConnectionFactory connectionFactory = new ActiveMQSslConnectionFactory(url);
connectionFactory.setUserName(username);
connectionFactory.setPassword(password);
connectionFactory.setTrustStore(trustStorePath);
connectionFactory.setTrustStorePassword(new String(trustStorePassword));
connectionFactory.setExceptionListener(this);
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
@Override
public void onException(JMSException e) {
logger.error("Unexpected JMS exception caught", e);
}
}
I am wondering if it is safe to pass a reference to this from the JmsCode constructor given that the object hasn't been fully constructed yet. I came across a similar question which had me reading up on IBM's article on not publishing this during construction. While I agree with their reasoning, I am not sure if it applies in this case since the only thing the exception listener is doing is logging via a static and final member. Is the code above safe (ignoring someone else being tempted to change the exception listener method to use some instance state of the object)?
java constructor
add a comment |
I came across some JMS calling code that initializes the JMS session inside of its constructor. The calling code implements the ExceptionListener interface and passes a reference to this to the connection factory object, as shown below:
public class JmsCode implements ExceptionListener {
private static final Logger logger = LoggerFactory.getLogger(JmsCode.class);
public JmsCode(String url, String username, String password, String trustStorePath, char trustStorePassword) throws JMSException {
ActiveMQSslConnectionFactory connectionFactory = new ActiveMQSslConnectionFactory(url);
connectionFactory.setUserName(username);
connectionFactory.setPassword(password);
connectionFactory.setTrustStore(trustStorePath);
connectionFactory.setTrustStorePassword(new String(trustStorePassword));
connectionFactory.setExceptionListener(this);
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
@Override
public void onException(JMSException e) {
logger.error("Unexpected JMS exception caught", e);
}
}
I am wondering if it is safe to pass a reference to this from the JmsCode constructor given that the object hasn't been fully constructed yet. I came across a similar question which had me reading up on IBM's article on not publishing this during construction. While I agree with their reasoning, I am not sure if it applies in this case since the only thing the exception listener is doing is logging via a static and final member. Is the code above safe (ignoring someone else being tempted to change the exception listener method to use some instance state of the object)?
java constructor
add a comment |
I came across some JMS calling code that initializes the JMS session inside of its constructor. The calling code implements the ExceptionListener interface and passes a reference to this to the connection factory object, as shown below:
public class JmsCode implements ExceptionListener {
private static final Logger logger = LoggerFactory.getLogger(JmsCode.class);
public JmsCode(String url, String username, String password, String trustStorePath, char trustStorePassword) throws JMSException {
ActiveMQSslConnectionFactory connectionFactory = new ActiveMQSslConnectionFactory(url);
connectionFactory.setUserName(username);
connectionFactory.setPassword(password);
connectionFactory.setTrustStore(trustStorePath);
connectionFactory.setTrustStorePassword(new String(trustStorePassword));
connectionFactory.setExceptionListener(this);
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
@Override
public void onException(JMSException e) {
logger.error("Unexpected JMS exception caught", e);
}
}
I am wondering if it is safe to pass a reference to this from the JmsCode constructor given that the object hasn't been fully constructed yet. I came across a similar question which had me reading up on IBM's article on not publishing this during construction. While I agree with their reasoning, I am not sure if it applies in this case since the only thing the exception listener is doing is logging via a static and final member. Is the code above safe (ignoring someone else being tempted to change the exception listener method to use some instance state of the object)?
java constructor
I came across some JMS calling code that initializes the JMS session inside of its constructor. The calling code implements the ExceptionListener interface and passes a reference to this to the connection factory object, as shown below:
public class JmsCode implements ExceptionListener {
private static final Logger logger = LoggerFactory.getLogger(JmsCode.class);
public JmsCode(String url, String username, String password, String trustStorePath, char trustStorePassword) throws JMSException {
ActiveMQSslConnectionFactory connectionFactory = new ActiveMQSslConnectionFactory(url);
connectionFactory.setUserName(username);
connectionFactory.setPassword(password);
connectionFactory.setTrustStore(trustStorePath);
connectionFactory.setTrustStorePassword(new String(trustStorePassword));
connectionFactory.setExceptionListener(this);
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
@Override
public void onException(JMSException e) {
logger.error("Unexpected JMS exception caught", e);
}
}
I am wondering if it is safe to pass a reference to this from the JmsCode constructor given that the object hasn't been fully constructed yet. I came across a similar question which had me reading up on IBM's article on not publishing this during construction. While I agree with their reasoning, I am not sure if it applies in this case since the only thing the exception listener is doing is logging via a static and final member. Is the code above safe (ignoring someone else being tempted to change the exception listener method to use some instance state of the object)?
java constructor
java constructor
edited Dec 29 '18 at 7:45
Hmmmmm
asked Dec 29 '18 at 2:25
HmmmmmHmmmmm
349110
349110
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
This is in fact unsafe publishing, and it's theoretically possible for another object to see this one in an inconsistent state.
That said, while this isn't a good pattern (and it's just shown here to demonstrate ExceptionListener
), the logic of the constructor shows that the class is in fact fully constructed by the time that the this
reference escapes (because it has nothing to construct), and so in this exact case there's nothing that can go wrong.
Could something go wrong if another thread, started by the factory object, tried to call the onException method on this? This is obviously hypothetical since I don't expect that to happen here but it may change how we implement further logic down the road.
– Hmmmmm
Dec 29 '18 at 7:47
@Hmmmmm In general, yes, something could go wrong. In this particular case, there is nothing to go wrong (no state to be inconsistent). Note that "down the road", you will probably be using a container such as Spring to handle things like JMS connection management, and you certainly would split up the connection management and your exception handler into separate classes.
– chrylis
Dec 29 '18 at 16:20
add a comment |
Whether it is safe or not depends on where that reference to this
can escape to. If, as a consequence of this call, this
could be read by another thread, then it is not safe.
If you want to ensure an instance is completely initialized for safe publication and you want to publish it, a constructor isn't the right place to publish it. Instead, you'll need to create a Factory object or a static factory method which can construct the object safely and then publish it before returning it to the caller.
Valid point. I actually removed a lot of the code to make it easier to read (and to not get in trouble for posting our code). The constructor is private and called from an old-school double lock check getInstance method.
– Hmmmmm
Dec 29 '18 at 7:36
add a comment |
It is completely safe. You are just passing the this
reference, not using anything in the this
scope.
Something will go wrong on that iff the .setExceptionListener(this)
method performs something else than being a setter.
My fear is exactly what you mentioned, if setExceptionListener does more than just being a setter. Let's say, hypothetically, that the local JMS client is already in a bad state and this info is cached somewhere so there is an immediate knowledge of an exception. Let's also say that, in another thread, it immediately tries to call the onException function, before the constructor had completed. What would the behavior be?
– Hmmmmm
Dec 29 '18 at 7:44
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53966193%2fpassing-this-in-constructor%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
This is in fact unsafe publishing, and it's theoretically possible for another object to see this one in an inconsistent state.
That said, while this isn't a good pattern (and it's just shown here to demonstrate ExceptionListener
), the logic of the constructor shows that the class is in fact fully constructed by the time that the this
reference escapes (because it has nothing to construct), and so in this exact case there's nothing that can go wrong.
Could something go wrong if another thread, started by the factory object, tried to call the onException method on this? This is obviously hypothetical since I don't expect that to happen here but it may change how we implement further logic down the road.
– Hmmmmm
Dec 29 '18 at 7:47
@Hmmmmm In general, yes, something could go wrong. In this particular case, there is nothing to go wrong (no state to be inconsistent). Note that "down the road", you will probably be using a container such as Spring to handle things like JMS connection management, and you certainly would split up the connection management and your exception handler into separate classes.
– chrylis
Dec 29 '18 at 16:20
add a comment |
This is in fact unsafe publishing, and it's theoretically possible for another object to see this one in an inconsistent state.
That said, while this isn't a good pattern (and it's just shown here to demonstrate ExceptionListener
), the logic of the constructor shows that the class is in fact fully constructed by the time that the this
reference escapes (because it has nothing to construct), and so in this exact case there's nothing that can go wrong.
Could something go wrong if another thread, started by the factory object, tried to call the onException method on this? This is obviously hypothetical since I don't expect that to happen here but it may change how we implement further logic down the road.
– Hmmmmm
Dec 29 '18 at 7:47
@Hmmmmm In general, yes, something could go wrong. In this particular case, there is nothing to go wrong (no state to be inconsistent). Note that "down the road", you will probably be using a container such as Spring to handle things like JMS connection management, and you certainly would split up the connection management and your exception handler into separate classes.
– chrylis
Dec 29 '18 at 16:20
add a comment |
This is in fact unsafe publishing, and it's theoretically possible for another object to see this one in an inconsistent state.
That said, while this isn't a good pattern (and it's just shown here to demonstrate ExceptionListener
), the logic of the constructor shows that the class is in fact fully constructed by the time that the this
reference escapes (because it has nothing to construct), and so in this exact case there's nothing that can go wrong.
This is in fact unsafe publishing, and it's theoretically possible for another object to see this one in an inconsistent state.
That said, while this isn't a good pattern (and it's just shown here to demonstrate ExceptionListener
), the logic of the constructor shows that the class is in fact fully constructed by the time that the this
reference escapes (because it has nothing to construct), and so in this exact case there's nothing that can go wrong.
answered Dec 29 '18 at 3:29
chrylischrylis
50.6k1680117
50.6k1680117
Could something go wrong if another thread, started by the factory object, tried to call the onException method on this? This is obviously hypothetical since I don't expect that to happen here but it may change how we implement further logic down the road.
– Hmmmmm
Dec 29 '18 at 7:47
@Hmmmmm In general, yes, something could go wrong. In this particular case, there is nothing to go wrong (no state to be inconsistent). Note that "down the road", you will probably be using a container such as Spring to handle things like JMS connection management, and you certainly would split up the connection management and your exception handler into separate classes.
– chrylis
Dec 29 '18 at 16:20
add a comment |
Could something go wrong if another thread, started by the factory object, tried to call the onException method on this? This is obviously hypothetical since I don't expect that to happen here but it may change how we implement further logic down the road.
– Hmmmmm
Dec 29 '18 at 7:47
@Hmmmmm In general, yes, something could go wrong. In this particular case, there is nothing to go wrong (no state to be inconsistent). Note that "down the road", you will probably be using a container such as Spring to handle things like JMS connection management, and you certainly would split up the connection management and your exception handler into separate classes.
– chrylis
Dec 29 '18 at 16:20
Could something go wrong if another thread, started by the factory object, tried to call the onException method on this? This is obviously hypothetical since I don't expect that to happen here but it may change how we implement further logic down the road.
– Hmmmmm
Dec 29 '18 at 7:47
Could something go wrong if another thread, started by the factory object, tried to call the onException method on this? This is obviously hypothetical since I don't expect that to happen here but it may change how we implement further logic down the road.
– Hmmmmm
Dec 29 '18 at 7:47
@Hmmmmm In general, yes, something could go wrong. In this particular case, there is nothing to go wrong (no state to be inconsistent). Note that "down the road", you will probably be using a container such as Spring to handle things like JMS connection management, and you certainly would split up the connection management and your exception handler into separate classes.
– chrylis
Dec 29 '18 at 16:20
@Hmmmmm In general, yes, something could go wrong. In this particular case, there is nothing to go wrong (no state to be inconsistent). Note that "down the road", you will probably be using a container such as Spring to handle things like JMS connection management, and you certainly would split up the connection management and your exception handler into separate classes.
– chrylis
Dec 29 '18 at 16:20
add a comment |
Whether it is safe or not depends on where that reference to this
can escape to. If, as a consequence of this call, this
could be read by another thread, then it is not safe.
If you want to ensure an instance is completely initialized for safe publication and you want to publish it, a constructor isn't the right place to publish it. Instead, you'll need to create a Factory object or a static factory method which can construct the object safely and then publish it before returning it to the caller.
Valid point. I actually removed a lot of the code to make it easier to read (and to not get in trouble for posting our code). The constructor is private and called from an old-school double lock check getInstance method.
– Hmmmmm
Dec 29 '18 at 7:36
add a comment |
Whether it is safe or not depends on where that reference to this
can escape to. If, as a consequence of this call, this
could be read by another thread, then it is not safe.
If you want to ensure an instance is completely initialized for safe publication and you want to publish it, a constructor isn't the right place to publish it. Instead, you'll need to create a Factory object or a static factory method which can construct the object safely and then publish it before returning it to the caller.
Valid point. I actually removed a lot of the code to make it easier to read (and to not get in trouble for posting our code). The constructor is private and called from an old-school double lock check getInstance method.
– Hmmmmm
Dec 29 '18 at 7:36
add a comment |
Whether it is safe or not depends on where that reference to this
can escape to. If, as a consequence of this call, this
could be read by another thread, then it is not safe.
If you want to ensure an instance is completely initialized for safe publication and you want to publish it, a constructor isn't the right place to publish it. Instead, you'll need to create a Factory object or a static factory method which can construct the object safely and then publish it before returning it to the caller.
Whether it is safe or not depends on where that reference to this
can escape to. If, as a consequence of this call, this
could be read by another thread, then it is not safe.
If you want to ensure an instance is completely initialized for safe publication and you want to publish it, a constructor isn't the right place to publish it. Instead, you'll need to create a Factory object or a static factory method which can construct the object safely and then publish it before returning it to the caller.
answered Dec 29 '18 at 3:32
Daniel PrydenDaniel Pryden
45.5k873117
45.5k873117
Valid point. I actually removed a lot of the code to make it easier to read (and to not get in trouble for posting our code). The constructor is private and called from an old-school double lock check getInstance method.
– Hmmmmm
Dec 29 '18 at 7:36
add a comment |
Valid point. I actually removed a lot of the code to make it easier to read (and to not get in trouble for posting our code). The constructor is private and called from an old-school double lock check getInstance method.
– Hmmmmm
Dec 29 '18 at 7:36
Valid point. I actually removed a lot of the code to make it easier to read (and to not get in trouble for posting our code). The constructor is private and called from an old-school double lock check getInstance method.
– Hmmmmm
Dec 29 '18 at 7:36
Valid point. I actually removed a lot of the code to make it easier to read (and to not get in trouble for posting our code). The constructor is private and called from an old-school double lock check getInstance method.
– Hmmmmm
Dec 29 '18 at 7:36
add a comment |
It is completely safe. You are just passing the this
reference, not using anything in the this
scope.
Something will go wrong on that iff the .setExceptionListener(this)
method performs something else than being a setter.
My fear is exactly what you mentioned, if setExceptionListener does more than just being a setter. Let's say, hypothetically, that the local JMS client is already in a bad state and this info is cached somewhere so there is an immediate knowledge of an exception. Let's also say that, in another thread, it immediately tries to call the onException function, before the constructor had completed. What would the behavior be?
– Hmmmmm
Dec 29 '18 at 7:44
add a comment |
It is completely safe. You are just passing the this
reference, not using anything in the this
scope.
Something will go wrong on that iff the .setExceptionListener(this)
method performs something else than being a setter.
My fear is exactly what you mentioned, if setExceptionListener does more than just being a setter. Let's say, hypothetically, that the local JMS client is already in a bad state and this info is cached somewhere so there is an immediate knowledge of an exception. Let's also say that, in another thread, it immediately tries to call the onException function, before the constructor had completed. What would the behavior be?
– Hmmmmm
Dec 29 '18 at 7:44
add a comment |
It is completely safe. You are just passing the this
reference, not using anything in the this
scope.
Something will go wrong on that iff the .setExceptionListener(this)
method performs something else than being a setter.
It is completely safe. You are just passing the this
reference, not using anything in the this
scope.
Something will go wrong on that iff the .setExceptionListener(this)
method performs something else than being a setter.
answered Dec 29 '18 at 2:32
KaNa0011KaNa0011
489311
489311
My fear is exactly what you mentioned, if setExceptionListener does more than just being a setter. Let's say, hypothetically, that the local JMS client is already in a bad state and this info is cached somewhere so there is an immediate knowledge of an exception. Let's also say that, in another thread, it immediately tries to call the onException function, before the constructor had completed. What would the behavior be?
– Hmmmmm
Dec 29 '18 at 7:44
add a comment |
My fear is exactly what you mentioned, if setExceptionListener does more than just being a setter. Let's say, hypothetically, that the local JMS client is already in a bad state and this info is cached somewhere so there is an immediate knowledge of an exception. Let's also say that, in another thread, it immediately tries to call the onException function, before the constructor had completed. What would the behavior be?
– Hmmmmm
Dec 29 '18 at 7:44
My fear is exactly what you mentioned, if setExceptionListener does more than just being a setter. Let's say, hypothetically, that the local JMS client is already in a bad state and this info is cached somewhere so there is an immediate knowledge of an exception. Let's also say that, in another thread, it immediately tries to call the onException function, before the constructor had completed. What would the behavior be?
– Hmmmmm
Dec 29 '18 at 7:44
My fear is exactly what you mentioned, if setExceptionListener does more than just being a setter. Let's say, hypothetically, that the local JMS client is already in a bad state and this info is cached somewhere so there is an immediate knowledge of an exception. Let's also say that, in another thread, it immediately tries to call the onException function, before the constructor had completed. What would the behavior be?
– Hmmmmm
Dec 29 '18 at 7:44
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53966193%2fpassing-this-in-constructor%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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