I'm trying to learn whether in Java 8, a nested static class in a controller (singleton class) is also static and could be shared between requests?
This is legacy code I'm cleaning up because of a possible race condition: The controller had multiple private fields. I moved them to a static nested class and created an instance of that class each time the request hits the controller. Then I pass that object around to private methods for calculations.
I'm being told that static nested classes in singletons have only one instance of the sub-class in memory, and if it's hit with 2 requests, the second one will stick. Also being warned that someone could move this static class outside, which is not a good approach to take (?)
There are a lot of answers around the difference between static class & singletons. Have found on Oracle docs: In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience.
=== But I haven't found anything about a static nested class IN a singleton ===
I tried it out: paused a thread in handleRequest and started a second one, and found the instances of the static nested class were different and contained different values. This is what I expect, given the documentation, but I don't know for sure, because I can't find anything about a static nested class WITHIN A SINGLETON.
Am I missing something? Is it possible this will fail? Is there a better solution?
public class MyController extends WebContentGenerator implements Controller {
#Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception
{
ReportParameters params = new ReportParameters();
initVars(request, params);
doWork(params);
return null;
}
private void initVars(HttpServletRequest request, ReportParameters params)
{
params.flag = "Y".equals(request.getParameter("flag"));
params.message = "Hello world";
}
private void doWork(ReportParameters params)
{
if (params.flag)
params.message = "foo";
}
private static class ReportParameters
{
private boolean flag;
private String message;
}
}
A static nested class is no different than a top-level class: every time you use new to create an instance, you... create an instance. If you create an instance more than once, then by definition, it's not a singleton. The fact that it's created from a singleton is competely irrelevant. The JVM doesn't even have the notion of a singleton: it's just an architectural choice.
Related
After reading the lazy initialization of expensive resources in the book around Page 106-108 - functional programming in Java by Venkat Subramaniam, it is found hard to understand the tricks with this code snippet
my understandings:
variable heavy in class Holder is of type Supplier<Heavy>
vs
local class HeavyFactory inside the method createAndCacheHeavy is a sub class extends Supplier
It seems only run once to execute that lambda method and then alter the outer member variable of class Holder.heavy
I am confused about below code the heavy is then later assigned with new reference pointing to the sub class extends Supplier
please if anyone could share hints the tricks here to gain the advantages of author proposed to save performance penalty from synchronized keyword and also taking care of thread safety. It also mentioned virtual proxy pattern. Did I miss out any key info to understand it?
package fpij;
import java.util.function.Supplier;
public class Holder {
//only run once here? before heavy get reassigned to HeavyFactory, the local class to that lambda method?
private Supplier<Heavy> heavy = () -> createAndCacheHeavy();
public Holder() {
System.out.println("Holder created");
}
public Heavy getHeavy() {
//the 2nd time it will call always the HeavyFactory.heavyInstance?
return heavy.get();
}
private synchronized Heavy createAndCacheHeavy() {
//create a local class inside method? Is the real trick/hack here I missed out so it will avoid 2nd time the synchronized penalty?
class HeavyFactory implements Supplier<Heavy> {
private final Heavy heavyInstance = new Heavy();
public Heavy get() { return heavyInstance; }
}
if(!HeavyFactory.class.isInstance(heavy)) {
heavy = new HeavyFactory();
}
return heavy.get();
}
public static void main(final String[] args) {
final Holder holder = new Holder();
System.out.println("deferring heavy creation...");
System.out.println(holder.getHeavy());
System.out.println(holder.getHeavy());
}
}
package fpij;
public class Heavy {
public Heavy() { System.out.println("Heavy created"); }
public String toString() { return "quite heavy"; }
}
If you are really concerned on the cost of synchronized, there a simple way to make it work correctly while keeping the initialization lazy.
It use the property that the classloader ensure synchronization when the class is loaded. It garentee that no other thread will be able to access the class until it is fully loaded. And the class load is actually lazy: it load the class only when the class is actually used from the first time.
If the only feature of class HeavyFactory is to provide the singleton instance, it will be loaded only when the getInstance is called and all will play nicely.
class HeavyFactory {
private static final Heavy heavyInstance = initInstance();
public static Heavy getHeavyInstance() {
return heavyInstance;
}
private static Heavy initInstance() {
heavyInstance = new HeavyInstance();
[...] // Other init stuff
return heavyInstance;
}
}
Edit: The init of complex objects and wiring of dependencies is so common that frameworks like JEE or Spring have implemented ways to do simplify it.
If you use spring for example, you would be able to just declare a given service as a singleton and then declare a dependency on it where you need it. The init would be done when the spring framework initialize in proper order:
// We instruct spring to create a shared instance of heavy
// with #Component annotation
// The instance would be created eagerly at the start of the app.
#Component
public class Heavy {
public Heavy() { System.out.println("Heavy created"); }
public String toString() { return "quite heavy"; }
}
// For the example another service using the Heavy shared instance
#Component
public class ClientDependingOnHeavy {
// We ask spring to fill it automatically the shared instance for us.
#Autowired
private Heavy heavy;
public String foo() {
//So we can use the instance like any object.
System.out.println(heavy.toString());
}
}
Well spring or JEE are quite complex advanced frameworks. For a single case they would not be worth it at all. For a whole application it would make sense. You'd need quite some reading/tutorials to make the second example work if you don't already know them. But in the long run, it may be worth the effort.
As we know PowerMockito can prepare for test only one final, static, or private class like following:
#RunWith(PowerMockRunner.class)
#PrepareForTest(SomeClassNumber1.class)
public class SomeClassUnderTest{
#Before
public void setUp() throws Exception {
}
#Test
public void testSomeMethod() throws Exception {
}
}
But the method I am going to test uses more than one static classes. The thing I want to do looks like:
#RunWith(PowerMockRunner.class)
#PrepareForTest(SomeClassNumber1.class, SomeClassNumber2.class)
public class SomeClassUnderTest{
But #PrepareForTest has only one argument.
Edit: For instance the method will use singleton, factory or some static methods of different classes.
public class SomeClass {
private Session session;
private Object object;
public void someMethod(int userId) {
Session session = Session.getSession(userId);
Object object = Singleton.getInstance();
}
}
Note: The problem could be solved by using single responsibility principle. e.g. instead of using singleton inside the method that is going to be tested, I can extract it to another method like following, and mock it:
public class SomeClass {
private Session session;
private Object object;
public void someMethod(int userId) {
session = getSession(userId);
object = getInstance();
}
private getSession(userId) {
return Session.getSession(userId);
}
private Object getInstance(){
return Singleton.getInstance();
}
}
But this too doesn't seem good solution for me. It is better if PowerMockito or other testing tools have the feature that can mock several static classes at the same time.
Edit: For instance the method will use singleton, factory or some static methods of different classes.
You should not use static access to class members and methods in the first place, you should also avoid the Java singelton pattern, There are other possibilities to make sure you have only one instance of a class at runtime.
Having written this lets answer your question:
#PrepareForTest has only one argument.
This single argument may be an array:
#PrepareForTest({Class1.class,Class2.class})
I'm trying to mock the following class which contains some static members
public class ClientFact {
private static final String BASE_URL = Config.getProperty("prop1");
private static final String USERID = Config.getProperty("prop2");
......................
public static Client createClient() throws AppException {
}
}
but i'm running into issues with the static member variables which are populated by Config.getProperty. This class does a read on a properties file like so
public class Config {
...............
public static String getProperty(Param param) {
String value = null;
if (param != null) {
value = properties.getProperty(param.toString());
}
return value;
}
}
I'm trying to mock this call since i dont care about the loaded properties in my test. This is what ive tried
#RunWith(PowerMockRunner.class)
#PrepareForTest({ClientFact.class})
public class MyTests {
#Test
public void test() {
PowerMock.mockStaticPartial(Config.class, "getProperty");
EasyMock.expect(Config.getProperty(EasyMock.anyObject())).andReturn(EasyMock.anyString()).anyTimes();
PowerMock.mockStatic(ClientFact.class);
}
}
but its giving the following error...
java.lang.NoSuchMethodError: org/easymock/internal/MocksControl.createMock(Ljava/lang/Class;[Ljava/lang/reflect/Method;)Ljava/lang/Object;
at org.powermock.api.easymock.PowerMock.doCreateMock(PowerMock.java:2214)
at org.powermock.api.easymock.PowerMock.doMock(PowerMock.java:2163)
any ideas what im doign wrong here?
A non-answer: consider not making static calls there.
You see, that directly couples that one class to the implementation of that static method in some other class; for no real reason. (and for the record: it seems strange that a USER_ID String is a static field in your ClientFact class. Do you really intend that all ClientFacts are using the same USER_ID?!)
You could replace that static call with a non-static version (for example by introducing an interface); and then you can use dependency injection to make an instance of that interface available to your class under test. And then all your testing works without the need to Powermock.
Long story short: very often (but not always!) the need to turn to Powermock originates in production code which wasn't written to be testable (like in your case). Thus instead of using the big bad Powermock hammer to "fix" your testing problem, you should consider improving your production code.
You might want to listen to those videos to get a better understanding what I am talking about.
I want to externalize commonly used applicationlogic into a "utility class" called Helper. The applicationlogic needs other CDI beans to work.
Two possibilities:
a)
#SessionScoped
class ControllerWithCdiBean {
#Inject
Helper helper;
public void doIt() {
Object result = helpder.calculate();
}
}
#RequestScoped
class Helper{
#Inject
Service anyService;
public Object calculate() {
return anyService.calc();
}
}
b)
#SessionScoped
class ControllerWithStaticCallsViaDeltaspike {
public void doIt() {
Object result = Helpder.calculate();
}
}
class Helper{
private static Service anyService = BeanProvider.getContextualReference(Service.class);
public static Object calculate() {
return anyService.calc();
}
What about performance? Are there any notable differences? Both solutions are possible for me, is one solutions better than the other?
One disadvantage:
Helpder gets initialized for every Request.
Mark your Helper class as #ApplicationScoped. With this, you will have a single instance per application context.
Still, if it's just an utility class, it shouldn't be a managed bean at all. I would instead mark it as final, define a private constructor and mark all the methods as static. This is because since it's an utility class, it doesn't need to maintain any state.
I'm using OrmLite to handle persistence in an Android application.
The OrmLite documentation discusses DAO Enabled Objects, along with providing a class you can extend to tell OrmLite you want to have the Dao set on instances of the class that are retrieved from the database.
This has some nice properties, like letting object.update() and object.refresh() DTRT.
For non-database-generated objects, there is an object.setDao(Dao) method you can use.
Would it be problematic to instead just initialise a Dao as a static member variable on the class at start?
public class Order extends BaseDaoEnabled<Order, Integer> {
protected static globalDao = null;
public Order() {
// Set non-static dao used by parent BaseDaoEnabled
this.dao = globalDao;
}
In the main class of the program I would initialise globalDao once with a Dao appropriate for the object.
This would have the nice property of allowing us to do database operations given an instance of the class even without access to OrmLiteSqliteOpenHelper.getDao().
I think this is threadsafe, since my reading of DaoManager indicates there is generally only one Dao per class anyway.
[ Sorry for the late response. ]
Would it be problematic to instead just initialise a Dao as a static member variable on the class at start?
Yes and no. You need to make sure when the application closes that the DAO is set to null so it gets reinitialized when it comes back. The problem is that I've see applications that are stopped but the classes are still in memory. Then if the user re-runs the application the static initializers will not be reinstantiated and old versions of the DAO with now dead connections to the database will be in place.
The right thing to do is to mirror the behavior that the DatabaseHelper class uses in the HelloAndroid project. To paraphrase it:
public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
private Dao<SimpleData, Integer> simpleDao = null;
public Dao<SimpleData, Integer> getDao() throws SQLException {
if (simpleDao == null) {
simpleDao = getDao(SimpleData.class);
}
return simpleDao;
}
#Override
public void close() {
super.close();
simpleDao = null;
}