How to: user MessageBundle in a bean?

Hi,
working with JMIX 1.5,
how can I use MessageBundle in a bean?
In screen context it works, but not in unbound class!?

Is io.jmix.core.Messages the same as io.jmix.ui.screen.messageBundle?

Thanks in advance,
br
HP

Hello @Eichers ,

You can only use the MessageBundle component in a view controller. For services you need to use the Messages component.

Docs:
https://docs.jmix.io/1.x/jmix/1.5/localization/message-bundles.html#messages-interface

Regards,
Nikita

1 Like

Thanks Nikita,
having read the docs once again, I was struggling over the need to declare ‘messages’ in the class constructor. But with a constructor I can even user MessageBundle in a normal class.
Is this right? Is it the best way?

`
import io.jmix.core.Messages;
import io.jmix.email.Emailer;
import io.jmix.ui.screen.MessageBundle;

public class S7EMail {

private static Messages messages;
private static MessageBundle messageBundle = null;
private static Emailer emailer = null;

public S7EMail(MessageBundle messageBundle, Emailer emailer, Messages messages) {
S7EMail.messageBundle = messageBundle;
S7EMail.messages = messages;
S7EMail.emailer = emailer;
}

public static void sendInvitationEMail(String eMail) throws EmailException {
System.out.println(messages.getMessage(“io.jmix.my.app/eMailTemplateInvitation”));
}

}
`

Is it working?
I’m wondering if this would work if you put @Autowired annotation in front of Messages, MessageBundle and Emailer beans.

@Autowired
private Messages messages;

public S7EMail(MessageBundle amessageBundle, Emailer aemailer, Messages amessages) {

Kind regards,
Mladen

Works without @Autowired at the moment.
Will try your idea later.

What would be the advantage to use @Autowired?

Hi,

You should not make the method static. Static methods don’t have access to instance variables.

Then it should work :slight_smile:

Oh now I see - you also made your instance variables static.

I have never seen that pattern in spring app. Probably get rid of all static stuff.

1 Like

Long story short, with @Autowired, you let Spring framework manage the lifecycle of that object, which is one of the reasons to use Spring. If you don’t use it, you may get into problems later when you try to do some standard thing you expect Spring to handle, but it will not be able to, e.g. testing - or, you may want to use some addon or module that assumes it is handled by Spring but it isn’t.
This can also lead to some memory leaks.

Please try this:
image
—> @Autowired is generatd

Recently Haulmont added some examples and code snippets that are using “final” more often, but it’s “final”, not “static”.

Ofc, the first criteria for any code being “ok” is that it works. :slight_smile:

Kind regards,
Mladen

1 Like

Thanks to all of you!
My static nightmare started when IntelliJ thought, static would fix my missing initialization…
Still rookie level in Java I’ll have to read more about the mix of: class constructor, final, @Autowired, … as there seems to be more than one valid/working solution.

Actually I recovered, that if I use a constructor, I could omit @Autowired.

So in my Toolbox classes S7xxx:

//@Autowired
private final S7EMail S7EMail;
//@Autowired
private final UnconstrainedDataManager unconstrainedDataManager;

public S7Data(S7EMail S7EMail, UnconstrainedDataManager unconstrainedDataManager) {
    this.S7EMail = S7EMail;
    this.unconstrainedDataManager = unconstrainedDataManager;
}

both works. With @Autowired and also without.
I’ll find out…

Thanks in advance,
best regards,

HP

1 Like

Yes this is true, Spring added support for constructor based injection quite some time ago.

It is generally considered the preferred approach, as it doesn’t let objects be instantiated in an illegal state (one dependency is set but another one not e.g).

You can read more about it here: Why You Should Use Constructor Injection in Spring

Yes IDEA started generating static methods during e.g. “extract method” refactorings, but only if the method does not depend on an instance variable. That being said, when the method is already there and you want to use a new dependency, you have to make sure you remove the static keyword to access instance variables.

Cheers
Mario

1 Like

Hi, Mario,
thank you very much for these background infos!
Java and JMIX will rule my life for the next years, so I’m actually interested in all the gears behind and not only in a swift solution.
ciao,
HP