thread from static method Java - java

What I want to do is, pass clientId to ClearSession() and use clientId in run() to call session.loadByLastAccessed(). But the error it throws is...
Service.java:117: non-static variable this cannot be referenced from a static context
at Thread t = new Thread(new ClearSession(clientId)) (since it is inner class)
If I change the class to be static, it will throw an error on session.loadByLastAccessed(entityManager, clientId); since entityManager is non-static.
Any ideas on how to start() a thread from a static method and pass a non-static variable?
This is my code...
private EntityManager entityManager; //declared within class along with code below.
public static void initClients()
throws SessionServiceException
{
Properties properties = ApplicationConfig.getInstance().getProperties();
Set<Object> keys = properties.keySet();
String clientId = null;
for (Object keyObject : keys)
{
String key = (String)keyObject;
if (key.startsWith(SessionFactory.CLIENT_PREFIX))
{
clientId = StringUtils.substringAfter(key, SessionFactory.CLIENT_PREFIX);
SessionFactory.getSessionIntf(clientId);
}
}
if(!StringUtils.equals("branch", clientId ))
{
Thread t = new Thread(new ClearSession(clientId));
t.start();
}
}
private class ClearSession implements Runnable
{
private String clientId = "";
public ClearSession(String clientId)
{
this.clientId = clientId;
}
public void run()
{
try
{
// Pause for 2 hours
Thread.sleep(7200000);
// get client session
AbstractImpl session = SessionFactory.getSessionIntf(clientId);
session.loadByLastAccessed(entityManager, clientId);
} catch (InterruptedException ie) {
throw ie;
}
}
}

I see now. You have private class, it means it is inner class. By default inner classes implicitly reference outer class's this. Just declare the class as private static class or just move it outside.

Related

How to test void method with no parameters?

I have method that is called by another service and it just change one of the field for some rows in database. Method looks like this:
void errorOrders() {
List<Orders> orders = OrderDAO.getErrorOrders(); //select only fields with status 'error'
orders.forEach(order -> order.setStatus(OrderStatus.NEW);
//some logging etc.
}
Is there any way to unit test this method? Can I inject myself inside this method and check if orders status was changed?
Cheers!
I would recommend you refactor your class to make your code testable. Ideally you would inject the dependency that represents the OrderDAO:
class ErrorChecker {
private final OrderDAO orderDAO;
public ErrorChecker(OrderDAO orderDAO) {
this.orderDAO = orderDAO;
}
public void errorOrders() {
List<Orders> orders = orderDAO.getErrorOrders();
orders.forEach(order -> order.setStatus(OrderStatus.NEW);
}
}
Then your test code would look like:
#Test
void testErrorOrders() {
Order order1 = mock(Order.class);
Order order2 = mock(Order.class);
OrderDAO orderDAO = mock(OrderDAO.class);
when(orderDAO.getErrorOrders()).thenReturn(List.of(order1, order2));
ErrorChecker errorChecker = new ErrorChecker(orderDAO);
errorChecker.errorOrders();
verify(order1).setState(OrderStatus.NEW);
verify(order2).setState(OrderStatus.NEW);
}
There are ways to mock static methods but I would recommend refactoring to inject the dependencies as it has many other benefits beside testability.
If you need to leave the method as static then you can still mock it (in v3.4+ of Mockito):
#Test
void testErrorOrders() {
try (MockedStatic mocked = mockStatic(OrderDAO.class)) {
mocked.when(OrderDAO.getErrorOrders()).thenReturn(List.of(order1, order2));
ErrorChecker errorChecker = new ErrorChecker(orderDAO);
errorChecker.errorOrders();
mocked.verify(order1).setState(OrderStatus.NEW);
}
}
#ismail and #khelwood already provided good answers.
If you mock the Object, you can control/see what happens to it
If you change an Object, where you can access the state via public methods, use those
If you change an Object whose state you cannot access with normal code, use Java Reflections to look at member variables.
If you set up Objects, that pass their data to streams and other output, you can put some additional streams etc in between. Use inheritance and reflection if necessary
Simple example of using Reflection on a shielded class:
package stackoverflow.simplefieldaccess;
public class ShieldedClass {
private int mStatus;
public ShieldedClass() {
mStatus = 666;
}
public void setStatus(final int pStatus) {
mStatus = pStatus; // usually with ints be careful and do checks here, but for the sake of simplicity we leave that out
}
#Override public String toString() {
return getClass().getSimpleName() + "[status:" + mStatus + "]";
}
}
Code to access it via reflection in a few ways:
package stackoverflow.simplefieldaccess;
import java.lang.reflect.Field;
import jc.lib.lang.reflect.JcFieldAccess;
public class SimpleFieldAccess {
public static void main(final String[] args) throws NoSuchFieldException, SecurityException {
final ShieldedClass so = new ShieldedClass();
System.out.println("Object.status before change: " + so);
so.setStatus(667);
System.out.println("Object.status after change: " + so);
System.out.println();
System.out.println("Accessing Object.status via Reflection...");
final Class<? extends ShieldedClass> cls = so.getClass();
final Field fieldToChance = cls.getDeclaredField("mStatus");
{
System.out.println("\nBad read access");
try { // will result in java.lang.IllegalAccessException
System.out.println("\tReading Object.status fiels via Reflection: " + fieldToChance.getInt(so));
throw new IllegalStateException("UNEXOECTED ERROR!");
} catch (final java.lang.IllegalAccessException e) {
System.out.println("\tAs expected: IllegalAccessException");
}
}
{
System.out.println("\nBad write access");
try { // will result in java.lang.IllegalAccessException
fieldToChance.set(so, Integer.valueOf(1337));
System.out.println("\tObject.status after change: " + so);
} catch (final java.lang.IllegalAccessException e) {
System.out.println("\tAs expected: IllegalAccessException");
}
}
{
System.out.println("\nGood manual read and write access");
final boolean isFieldOriginallyAccessible = fieldToChance.isAccessible();
try { // will result in java.lang.IllegalAccessException
if (!isFieldOriginallyAccessible) fieldToChance.setAccessible(true);
System.out.println("\tReading Object.status field via Reflection: " + fieldToChance.getInt(so));
fieldToChance.set(so, Integer.valueOf(4321));
System.out.println("\tObject.status after change: " + so);
} catch (final java.lang.IllegalAccessException e) {
e.printStackTrace();
} finally {
if (!isFieldOriginallyAccessible) fieldToChance.setAccessible(false);
}
}
{
System.out.println("\nGood automated read and write access");
try (JcFieldAccess fa = new JcFieldAccess(fieldToChance)) { // will result in java.lang.IllegalAccessException
System.out.println("\tReading Object.status field via Reflection: " + fieldToChance.getInt(so));
fieldToChance.set(so, Integer.valueOf(123));
System.out.println("\tObject.status after change: " + so);
} catch (final java.lang.IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
For reflections, when I want to access fields, I use my homebrew class that makes it easier to get access to the field and afterwards restore it to normal (last example above uses this):
package jc.lib.lang.reflect;
import java.io.Closeable;
import java.lang.reflect.AccessibleObject;
public class JcFieldAccess implements Closeable {
private final AccessibleObject mField;
private final boolean mIsAccessible;
public JcFieldAccess(final AccessibleObject pField) {
mField = pField;
mIsAccessible = mField.isAccessible();
if (!mIsAccessible) mField.setAccessible(true);
}
#Override public void close() {
if (mIsAccessible) return;
if (mField != null) mField.setAccessible(false);
}
}
The trick with this util class is that when used in a try-resource block, its close() method will get called automatically, whether the block fails or not. It's the same as having the close() or in this case setAccessible(false) call in the finally block, with some extra checks.
Let the class be:
class HandleErrorOrders {
private OrderDAO orderDAO;
HandleErrorOrders(final OrderDAO orderDAO) {
this.orderDAO = orderDAO;
}
public void errorOrders() {
List<Orders> orders = OrderDAO.getErrorOrders(); //select only fields with status 'error'
orders.forEach(order -> order.setStatus(OrderStatus.NEW);
//some logging etc.
}
}
You need to use assert methods to check end state.
To test, write something like:
class HandleErrorOrdersTest {
#Mock
private OrderDAO orderDAO;
#InjectMocks
private HandleErrorOrders handleErrorOrders;
#Test
void testErrorOrders() {
Order order1 = mock(Order.class);
Order order2 = mock(Order.class);
when(orderDAO.getErrorOrders()).thenReturn(List.of(order1, order2));
ErrorChecker errorChecker = new ErrorChecker(orderDAO);
errorChecker.errorOrders();
//asset checks
Assert.assertEquals(OrderStatus.NEW, order1.getStatus());
Assert.assertEquals(OrderStatus.NEW, order2.getStatus());
//verification checks
Mockito.verify(orderDAO).getErrorOrders();
}
}

Even created a global class, still cannot save a variable from try-catch

Android Studio topic
My story flow:
Created a GlobalClass for saving user info.
Login to a Facebook account to draw user info (JSONobject).
In an inner class (onSuccessListener), I want to save user name in my GlobalClass for later use.
AndroidStudio requests me to use try-catch for JSON exception. OK, I must use one then.
What I do is: try-(Draw user name from JSONObject when login success and save the user Nickname in GlobalClass) and catch-(exception). Done.
However, wherever outside the onSuccess inner class, my GlobalClass is null!
Any ideas?
updated with code: the "globalVariable.setGlobalUserFacebookName()" will have no value when leaving, for other user information, it can save.
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
accessToken = loginResult.getAccessToken();
#SuppressLint("StringFormatMatches") String tempText = String.format(getString(R.string.loginInformation,
loginResult.getAccessToken().getUserId(),
loginResult.getAccessToken().getToken(),
AccessToken.getCurrentAccessToken().getPermissions().toString()));
fbtoken.setText(tempText);
globalVariable.setGlobalUserFacebookID(loginResult.getAccessToken().getUserId());
globalVariable.setGlobalUserFacebookToken(loginResult.getAccessToken().getToken());
globalVariable.setGlobalUserFacebookPermission(AccessToken.getCurrentAccessToken().getPermissions().toString());
final String FirebaseEmail = globalVariable.getGlobalUserFirebaseEmail();
GraphRequest request = GraphRequest.newMeRequest(loginResult.getAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {// Application code
try {
FacebookUserName = (String) response.getJSONObject().getString("name");
// the value of this globalClass null after leaving this inner class
globalVariable.setGlobalUserFacebookName(FacebookUserName);
} catch (JSONException e) {
e.printStackTrace();
}
loggedInView.setText(FacebookUserName);
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "name");
request.setParameters(parameters);
request.executeAsync();
}
public class GlobalClass {
private static GlobalClass instance;
private static String globalUserFirebaseName;
private static String globalUserFirebaseEmail;
private static String globalUserFirebasePassword;
private static String globalUserFacebookName;
private static String globalUserFacebookID;
private static String globalUserFacebookToken;
private static String globalUserFacebookPermission;
public static void setInstance(GlobalClass instance) {
GlobalClass.instance = instance;
}
public static String getGlobalUserFirebaseName() {
return globalUserFirebaseName;
}
public static void setGlobalUserFirebaseName(String globalUserFirebaseName) {
GlobalClass.globalUserFirebaseName = globalUserFirebaseName;
}
public static String getGlobalUserFirebaseEmail() {
return globalUserFirebaseEmail;
}
public static void setGlobalUserFirebaseEmail(String globalUserFirebaseEmail) {
GlobalClass.globalUserFirebaseEmail = globalUserFirebaseEmail;
}
public static String getGlobalUserFirebasePassword() {
return globalUserFirebasePassword;
}
public static void setGlobalUserFirebasePassword(String globalUserFirebasePassword) {
GlobalClass.globalUserFirebasePassword = globalUserFirebasePassword;
}
public static String getGlobalUserFacebookName() {
return globalUserFacebookName;
}
public static void setGlobalUserFacebookName(String globalUserFacebookName) {
GlobalClass.globalUserFacebookName = globalUserFacebookName;
}
public static String getGlobalUserFacebookID() {
return globalUserFacebookID;
}
public static void setGlobalUserFacebookID(String globalUserFacebookID) {
GlobalClass.globalUserFacebookID = globalUserFacebookID;
}
public static String getGlobalUserFacebookToken() {
return globalUserFacebookToken;
}
public static void setGlobalUserFacebookToken(String globalUserFacebookToken) {
GlobalClass.globalUserFacebookToken = globalUserFacebookToken;
}
public static String getGlobalUserFacebookPermission() {
return globalUserFacebookPermission;
}
public static void setGlobalUserFacebookPermission(String globalUserFacebookPermission) {
GlobalClass.globalUserFacebookPermission = globalUserFacebookPermission;
}
public static synchronized GlobalClass getInstance() {
if(instance == null) {
instance = new GlobalClass();
}
return instance;
}
}
According to csell's answer, which is correct, this is just a matter of scope.
You can read more oracle's official doc about anonymous class and the final keyword to solve your problem.
You should consider making only the field "instance" of the GlobalInstance to be static for singleton use. Others fields should be at object's instance level (non-staic) to make sure that you always use the same global variable, and you go more into abstraction/encapsulation.
If an object is created inside a class then that object can only be referenced inside that class unless you create a method which returns that object. With that said, any class with access to the object can call the methods associated with that object. This does not mean the variables can be seen though. In order for the variable values to be retrieved, you must have methods returning those values, like you have in GlobalClass. Thus, the problem is related to scope.

Inject EJB in #serverEndpoint class results in NullPointerException

I'm using Swarm Wildfly to deploy this application.
Basically I'm making a websocket enabled application.
I'd like to inject a singleton which will be started on the startup which modify the variable result.
Upon accessing the "/rafflethis" link, user will be able to see the result which will be sent via session.
The result is that the roll variable null
This is the class
#Singleton
#Startup
#ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class runMe implements RaffleManager{
private static final Logger LOGGER = Logger.getLogger(runMe.class.getName());
private static String result;
#PostConstruct
public void onStartup() {
System.out.println("Initialization success.");
}
#Schedule(second = "*/10", minute = "*", hour = "*", persistent = false)
public void run() throws Exception{
int i = 0;
while (true) {
Thread.sleep(1000L);
result = UUID.randomUUID().toString().toUpperCase();
i++;
LOGGER.log(Level.INFO, "i : " + i);
}
}
public String getResult() {
return result;
}
}
interface
public interface RaffleManager {
String getResult();
}
And the "/rafflethis"
#ServerEndpoint("/rafflethis")
public class RaffleThis implements Serializable {
#EJB
RaffleManager roll;
private static final Set<Session> sessions = Collections.synchronizedSet(new HashSet<Session>());
private static void sendMessageToAll(String message) {
for (Session s : sessions) {
try {
s.getBasicRemote().sendText(message);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
#OnOpen
public void monitorLuckyDip(Session session) throws Exception {
sessions.add(session);
while(true) {
sendMessageToAll(roll.getResult());
}
}
}
Any lead where should I head from this? Thanks!
Looking at the source, I would probably assume a name issue.
Your singleton bean "runMe" is the actual name of the bean not the interface.
SIDE NOTE: Best practice for class names is capitalize the first letter. RunMe instead of runMe.
#Singleton - without parameters will automatically name your bean for lookup using the bean convention from your class name. Imagine if you implement multiple interface, how does EJB pick the name? So it is just logical to use the class name. E.g. If your classname is TestMe, the ejb name will be testMe.
In your case since your class name is runMe, I would think the bean name will be runMe.
To ensure the lookup will not fail, you can specific the name in #Singleton and #EJB.
#Singleton(name = "runMe")
#Startup
#ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class runMe implements RaffleManager{
Then in your Service end point class
#ServerEndpoint("/rafflethis")
public class RaffleThis implements Serializable {
#EJB(beanName ="runMe")
RaffleManager roll;
The solution is rather hacky but a very simple one indeed. Take a look at the provided diagram.
And here's the code
Logic Implementation:
#Startup
#Singleton
public class RunMe{
private static final Logger LOGGER = Logger.getLogger(RunMe.class.getName());
#Inject
MessageDTO messageDTO;
#PostConstruct
public void onStartup() {
System.out.println("Initialization success.");
}
#Schedule(second = "*/10", minute = "*", hour = "*", persistent = false)
public void run() throws Exception{
//You can also substitute this method with constructor of the class -- removing the #Schedule annotation.
int i = 0;
while (true) {
Thread.sleep(1000L);
messageDTO.setText(UUID.randomUUID().toString().toUpperCase());
i++;
LOGGER.log(Level.INFO, "i : " + i);
}
}
}
MessageDTO:
#Singleton
public class MessageDTO {
private static String text;
public static String getText() {
return text;
}
public static void setText(String text) {
MessageDTO.text = text;
}
}
Websocket Implementation:
#ServerEndpoint("/rafflethis")
public class RaffleThis implements Serializable {
private static final Logger LOGGER = Logger.getLogger(RaffleThis.class.getName());
private static final Set<Session> sessions = Collections.synchronizedSet(new HashSet<Session>());
#Inject
MessageDTO messageDTO;
private static void sendMessageToAll(String message) {
for (Session s : sessions) {
try {
s.getBasicRemote().sendText(message);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
#OnOpen
public void monitorLuckyDip(Session session) throws Exception {
sessions.add(session);
while (true) {
Thread.sleep(200);
sendMessageToAll(messageDTO.getText());
}
}
}

Static Field as Null when mocking Enums with PowerMock

I have written a Thread Pool and I am not able to write the Junits(PowerMock) for that class.
public enum ThreadPool {
INSTANCE;
private static final String THREAD_POOL_SIZE = "threadpool.objectlevel.size";
private static TPropertyReader PROP_READER = new PropertyReader();
private final ExecutorService executorService;
private static final ILogger LOGGER = LoggerFactory
.getLogger(ReportExecutorObjectLevelThreadPool.class.getName());
ThreadPool() {
loadProperties();
int no_of_threads = getThreadPoolSize();
executorService = Executors.newFixedThreadPool(no_of_threads);
}
public void submitTask(Runnable task) {
executorService.execute(task);
}
private static void loadProperties() {
try {
PROP_READER.loadProperties("Dummy");
} catch (final OODSystemException e) {
LOGGER.severe("Loading properties for app failed!");
}
}
private int getThreadPoolSize() {
return Integer.valueOf(PROP_READER
.getProperty(THREAD_POOL_SIZE));
}
}
While Mocking this class I am getting NullPointerException in the line PROP_READER.loadProperties("DUMMY");
My Test Case is:-
PowerMockito.whenNew(PropertyReader.class).withNoArguments().thenReturn(mockPropertyReader);
PowerMockito.doNothing().when( mockPropertyReader,"loadProperties",anyString());
mockStatic(ThreadPool.class);
First you need to set your internal state of your enum as enum is final class
and the instance of an enum will be load on class loading
ThreadPool mockInstance = mock(ThreadPool .class);
Whitebox.setInternalState(ThreadPool.class, "INSTANCE", mockInstance);
then
PowerMockito.mockStatic(ThreadPool .class);
and then mocking
doNothing().when(mockInstance).loadProperties(any(String.class));
do not forget adding the following annotation to the test
#RunWith(PowerMockRunner.class)
#PrepareForTest({ThreadPool.class})
if it still not working you need to see which more member of the class you need to set in the internal state

How to call parent class objects within a subclass?

I'm not sure if I'm asking this right, as I'm attempting to teach myself Java. I have a class which contains my main method, and within this class are several subclasses that need access to my user settings using java.util.Properties. I have to create the properties object in every subclass in order to make it work, and I can't reference the object using configFilePath, it must be null. I'm wondering if I can create this public object within the parent class, so I don't need to create it in all of its subclasses? Here is my code, I'm really not sure I'm doing this right although it works.
public class Frame1 extends JFrame {
Settings config = new Settings(); //this is the object I want to reference within subclasses
class Update extends SwingWorker<Integer, Void> { //first subclass
#Override
protected Integer doInBackground() throws Exception {
Settings config = new Settings(configFilePath); //yet I have to create the object within every subclass, this time an argument is required.
String templateDir = config.getProperty("templatedir");
String writePath = config.getProperty("outputdir");
//do some logic code, not required for my question
}
#Override
protected void done() {
Update2 update2 = new Update2();
update2.execute(); //start the next subclass which also needs access to Settings(configFilePath)
}
}
}
public class Settings extends JFrame {
String configFilePath = "C:/path/to/settings.properties";
Properties properties = new Properties();
public Settings(String configFilePath) throws IOException {
this.configFilePath = configFilePath;
FileInputStream fis = null;
try {
fis = new FileInputStream(configFilePath);
properties.load(fis);
} catch (FileNotFoundException e) {
setDefaults();
} finally {
if (fis != null) {
fis.close();
}
}
}
}
I'm not sure if I'm doing this right or not, it seems to work but seems to be rather redundant having to create the config object every time I need to access my user settings. I hope this hasn't been asked before, and if it has please link me, as I could not find it.
You can create the Setting class as a Singleton pattern, here is one example:
public class Settings extends JFrame{
String configFilePath = "C:/path/to/settings.properties";
Properties properties = new Properties();
private static Settings instance;
public static Settings getInstance(){
if(instance==null){
instance = new Setting();
}
return instance;
}
private Settings() throws IOException {
FileInputStream fis = null;
try {
fis = new FileInputStream(configFilePath);
properties.load(fis);
} catch (FileNotFoundException e) {
setDefaults();
} finally {
if (fis != null) {
fis.close();
}
}
}
}
Usage in any other class of your system:
Settings.getInstance().getProperty("...");
From Update you can use Frame1.this to access the this of Frame1 (because Update is an inner class of Frame1).
Then to access config you can use Frame1.this.config.
Here is a working example:
public class PrefixerFactory {
private String prefix; // Used by Prefixer
public PrefixerFactory(String prefix) {
this.prefix = prefix;
}
public Prefixer createPrefixer() {
return new Prefixer();
}
public class Prefixer { // Inner class
public String addPrefix(String value) {
// Using "prefix" from PrefixerFactory
return PrefixerFactory.this.prefix + value;
}
}
public static void main(String[] args) {
Prefixer helloPrefixer = new PrefixerFactory("Hello ").createPrefixer();
Prefixer goodbyePrefixer = new PrefixerFactory("Good bye ").createPrefixer();
System.out.println(helloPrefixer.addPrefix("world")); // Hello world
System.out.println(goodbyePrefixer.addPrefix("world")); // Good bye world
}
}

Categories