The situation before:
A Resource exists. Class Root is created, and during it's creation it creates Child classes (many implementations of one base). Those can, but don't have to, posses children. Basically, this is a typical tree structure, that builds itself.
One of the Child classes "NeedyChild" requires access to a Resource that was opened during creation of Root. There was only one Resource possible, so I made it a singleton and accesed it from NeedyChild by Resource.getInstance();
The situation now:
I have to build many trees. Those are independent of each other and take quite some time, so I made it concurrent. Unfortunatelly, each tree has it's own Resource.
Question: how to access the Resource specific to the current runnable now?
My solutions:
Make Child base class require Resource parameter in it's constructor. Pros: it's quick. It's fairly efficient (passing a reference is no big deal), it's simple. Cons: it requires me to change constructor calls and signatures throughout the application, possibly >100 places.
Reflection to make base constructor find it's caller, save reference, then just give Resource to Root, and NeedyChild will go up "creators" hierarchy to get Root and then Resource. But I won't do that, it's evil.
Didn't research it, but maybe I can access the parent Runnable the code is currently executing inside? Cast it back to my RunnableClass which could hold reference to Resource? The problems are: I don't know if it's possible, it seems a bit "wrong" too...
(not really working) Make the tree traversable both ways, give Resource to Root and from NeedyChild getParent() long enough until you're at Root. It would be great, but the NeedyChild needs Resource during it's creation, and only after it is created, it is appended to the parent. I thought of delaying filling Resource-dependent fields, but it gets ugly very quick.
TBH I probably will have to modify the base constructor and either pass "this" (so I can traverse back to the Root), or pass Resource. The runnable-specific context seems also quite decent, but I'm already doing the parallel procesing to make things faster, I don't really want to negate it by some very slow reflection lookups...
So, any ideas?
Addendum 1: Sample Code
abstract class BaseElement{
List<BaseElement> children = new ArrayList<>();
public void addChild(BaseElement child){
children.add(child);
}
}
class Loader{
private PackageElement resultPackage;
private Resource resource;
public Loader(Resource resource){
this.resource = resource;
}
public callMeFromOutside(SourceTree source){
resultPackage = new Package(source.pack());
}
}
class PackageElement extends BaseElement {
public PackageElement(PackageTree pack){
this.addChild(new Element(pack.element()));
}
}
class Element extends BaseElement{
public Element(ElementTree element){
this.addChild(new NeedyChild(element.needyChild()));
}
}
class NeedyChild extends BaseElement{
public NeedyChild(NeedyTree needy){
this.setSomethingImportant(resource.loadSomethingBasedOn(needy));
}
}
Since there is a one-to-one correspondence between a tree and thread, modifying your singleton pattern to be thread-local should do the trick. For concreteness, here is a code sample:
public class Resource
{
private static final ThreadLocal<Resource> threadLocal = new ThreadLocal<Resource>();
public static Resource getInstance()
{
return threadLocal.get();
}
public static void setInstance(final Resource instance)
{
threadLocal.set(instance);
}
...
}
Just make sure that you call Resource.setInstance on the appropriate thread before instantiating NeedyChildobjects.
Related
Here is snippet of intrested case:
We have some configuration class it can have multi instances. It suppose that we supply several configurations in one bundle. It's one scope.
#Service
#Component
public class SampleConfigurationImpl implements SampleConfiguration {
// declaration of some properties, init method and etc...
}
Also we have a service which uses these configurations:
#Service
#Component
public class SampleServiceImpl implements SampleService {
#Reference(
referenceInterface = SampleConfiguration.class,
cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE,
policy = ReferencePolicy.DYNAMIC)
private Map<String, SampleConfiguration> sampleConfigurations = new ConcurrentHashMap<>();
private void bindSampleConfigurations(SampleConfiguration sampleConfiguration) {
sampleConfigurations.put(sampleConfiguration.getName(), sampleConfiguration);
}
private void unbindSampleConfigurations(SampleConfiguration sampleConfiguration) {
sampleConfigurations.remove(sampleConfiguration.getName());
}
#Activate
private void init() {
System.out.println(sampleConfigurations.size());
}
}
So, can I get some guarantees that on invocation of init method all configurations are injected (at least of current bundle)? Maybe there is some alternative way to do this. I understand that another bundles can bring new configurations and it's unreal to get guarantees but it's intrested in case of only one bundle.
On practice it can be case when in init method there are only part of configurations. Especially if it's more difficalt case when you have several types of configuration or one service uses another one which has dynamic references and first service relies on fact that everything is injected.
The most unpleasant is that it can bind/unbind configurations both before and after init method.
Maybe there is some way to guarantee that it bind always after init method...
I'm interested in any information. It will be great to get answer on two questions (guarantees before or after). Probably someone has experience how to resolve such problem and can share with me.
Thanks.
No, not that I know of. What I usually do in that case (depending on your use case, it depends on if your activation code is ok with running multiple times) is to create a 'reallyActivate' method I call both from the regular activate and from the bindSampleConfigurations (+ setting an isActivated flag in activate). Then I can perform some logic every time a new SampleConfiguration gets bound, even if it's after the activation. Does that help for your case?
I am starting with Java/Tomcat, and I am struggling with a problem that was very easy to solve with C++.
My webservice (sigle webapp) works by using the input values to lookup the numeric answer in a large, pre-calculated table. I am struggling with the initialization of this table.
Problem details:
The data table is huge (3000x3000);
The data is pre-computed and this computation is very costly (it
takes hours);
The data is static, it will never change after it is calculated for a
given instance;
In C++, I would just define a a static const array and initialize it inline. I was not able to do this in Java, apparently there's no concept of static data initialization in Java, it needs to generate initialization code and this code cannot be larger than 64k. In fact, I couldn't even load the file with the static initialization in Eclipse, it would hang-up.
So I need to initialize the table from a static file on disk. I tried to place a .csv file on WEB-INF/static, but found no way to open it reliably from inside my Java code (the absolute path will be in different places on my development and production environments, for example).
This is my current class definition (with mocked-up data for the initialization):
package com.hmt.restjersey;
public final class G {
static public final float[][] data = new float[3000][3000];
//TODO: actual initialization from file
static {
Logger.writeEventLog("Initializing G table...");
for (int alpha = 0; alpha < 3000; alpha++) {
for (int beta = 0; beta < 3000; beta++) {
data[alpha][beta] = 1.0f / (1 + alpha + beta);
}
}
Logger.writeEventLog("G table initialized.");
}
}
So, my questions:
How to reliably access the data file (WEB-INF/static/data.csv) to initialize the table?
Is a .csv file the best way to load numeric data efficiently?
Also, since the table is huge I would like to have a single instance of it in the server to save memory and speed up initialization. How do I assure that there will be a single instance shared by all servlet processes?
That's my two cents:
Regarding memory sharing, if all your servlets are in the same WAR (webapp) then they share static vars (because it's the same classloader), but it's even nicer to use ServletContext which is meant just for this, see ServletContext
As the ServletContext example (link above) shows, you don't necessarily need a static initializer - you can use ServletContextListener to init on application startup (btw you could also do initialization on-demand, in the 'getter' of your huge data).
If you'd like to share memory between 2 different WARs, I don't know a straightforward solution. Theoretically it can be shared if the class with the static var is in TOMCAT_HOME/lib, but iMHO it's confusing and weird
Putting the calculation in file/storage is a great idea, because you might find yourself restarting Tomcat!
As to how to locate the file, I agree with dmitrievanthony's comment regarding getResourceAsStream . Basically it allows you to take the file from your classpath (the same one used for locating code), one simple example would be putting it in /WEB-INF/classes/data.csv , see example code Here (I personally like when this approach is wrapped in "Resource" from Spring framework, but it could be an overkill).
Please note: As mentioned in my comment above, I tried to offer answers to your direct questions for the design you chose, but if I were in your shoes I'd stop to consider this design (e.g. is easy to distribute between servers? is it modular and unit-testable? Could "data.csv" be replaced with a database, or MongoDB, or even a separate "dataService" WAR?). But please ignore this remark if you're already considered it...
Edited: ServletContext example, without static fields:
// Class to encapsulate date:
public class G{
private double[][] data;
public static G loadData(){
data=...// complex loading
}
}
// Usage in ServletContextListener:
public class MyListener implements ServletContextListener{
public void contextInitialized(ServletContext ctx) {
G g= G.loadData();
ctx.put("myData", g);
}
// Usage is Servlet:
doGet(...){
G g=(G) getServletContext().getAttribute("myData");
}
Singleton pattern alternative (but I suggest care in terms of testability and modularity, you may also want to have a look at frameworks such as SpringMVC, but let's start simple):
// Singleton:
public class G{
private volatile double[][] data;
private G instance;
public static G getInstance(){
// I don't synchronize because I rely on ServletContextListener to initialize once
if(data==null)
data=... // complex loading
return data;
}
}
// ServletContextListener:
public void contextInitialized(ServletContext ctx) {
G.getInstance();
}
// Usage in servlet:
doGet(){
G g=G.getInstance(); // I don't like it in terms of OOD, but it works
}
Recently I came across with a builder pattern that intrigued me.
So, I have an EntityBuilder which builds an Entity, but it doesn't return the entity. Here is the method signature:
public void build();
Instead, inside the build() method, it delivers the new object created, the Entity, to a CacheImplementation instance to store it.
Note: the CacheImpl is injected in the builder's constructor.
public void build(){
//create new entity
cacheImplementation.add(entity);
}
Does this sounds like best practice?
Later edit 0
public interface EntityBuilder {
void setProperty0(PropertyObject propertyObject0);
void setProperty1(PropertyObject propertyObject1);
void setProperty2(PropertyObject propertyObject2);
//...
void build();
}
public class EntityBuilderImpl implements EntityBuilder {
PropertyObject propertyObject0;
PropertyObject propertyObject1;
PropertyObject propertyObject2;
//...
// setters for all properties
#Override
public void build(){
//create new entity
cacheImplementation.add(entity);
}
}
The builder is used in the following way:
public class EntityProcessor{
private EntityBuilderFactory entityBuilderFactory;//initialized in constructor
void process(EntityDetails entityDetails){
EntityBuilder entityBuilder = this.entityBuilderFactory.getNewEntitytBuilder();
//..
// entityBuilder.set all properties from entityDetails
entityBuilder.build();
}
}
Note: the cacheImpl instance just stores the entities in a List<> which is accesses every N seconds.
Does this sounds like best practice?
The traditional builder pattern doesn't store the created object anywhere, it simply returns it.
I can imagine a variation where the builder also has a role of instance control to avoid creating duplicate objects, and managing a store of immutable objects.
The decision to not return an instance could be to make it clear that the method has a side effect. If the method returned the object, it might mislead to thinking that it's a traditional builder without side effects, when that's not the case here.
In any case, all this is just speculation, as we haven't seen the rest of the code where this is used and the way it is implemented and used. We don't have enough context to really judge.
There's nothing wrong with inventing new patterns, but it can be done well or badly.
I've seen similar void build() method in the JCodeModel class. As you can see it throws IOException because of the resources it manages:
public void build(File destDir,
PrintStream status)
throws IOException
You basically ask it to carry out the operation for you and if no error is present - you can continue with the workflow.
In general builder is used in following way:
Some class will use builder to create class. Simple
Now you have additional piece of complexity - caching. You can put caching inside Builder or one level higher inside Processor.
What are the implications of putting cache management inside builder:
Builder does not have single responsibility anymore.
It does not work how you would expect at first glance
You are unable to create object without putting it into cache
These problems will not occur if you put cache management to separate class.
I would say that it is not terrible solution, but it certainly will decrease maintainability of your code.
This is probably a basic question that has some sort of solution that I am not aware of, but basically I have a apache-tomcat web application that hosts a lot of different sites and each visitor needs access to the contents of an xml file. There are about 6 different xml files that this could be. If I allow the file to be accessed each time (the file is used in lots of included pages and assets) I get too many files open, if I store it in the sessions, I get too much memory usage.
What I would like is when I compile the classes to have one class read each of the files into memory and then to access that data like a constant. Is there an easy way of doing this?
This is the classic case where a singleton would be useful. A singleton is often used to load content only once.
A modified example from the wikipedia page on Singletons (http://en.wikipedia.org/wiki/Singleton_pattern):
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private String xmlFileContents;
private Singleton() {
// Call method to populate xmlFileContents field from XML file
}
public static Singleton getInstance() {
return INSTANCE;
}
public String getXMLFileContents() {
return xmlFileContents;
}
}
I better explain the question with an example.
I have an Interface Model which can be used to access data.
There can be different implementations of Model which can represent the data in various format say XMl , txt format etc. Model is not concerned with the formats.
Lets say one such implementation is myxmlModel.
Now i want to force myxmlModel and every other implementation of Model to follow Singleton Pattern.The usual way is to make myxmlModels constructor private and provide a static factory method to return an instance of myModel class.But the problem is interface cannot have static method definitions and a result i cannot enforce a particular Factory method definition on all implementation of Model. So one implementation may end with providing getObject() and other may have getNewModel()..
One work around is to allow package access to myxmlModel's constructor and create a Factory class which creates the myxmlModel object and cache it for further use.
I was wondering if there is a better way to achieve the same functionality .
Make a factory that returns
instances of your interface, Model.
Make all concrete implementations of the model package-private classes
in the same package as your factory.
If your model is to be a singleton, and you are using java
5+, use enum instead of traditional
singleton, as it is safer.
public enum MyXMLModel{
INSTANCE();
//rest of class
};
EDIT:
Another possibility is to create delegate classes that do all the work and then use an enum to provide all of the Model Options.
for instance:
class MyXMLModelDelegate implements Model {
public void foo() { /*does foo*/}
...
}
class MyJSONModelDelegate implements Model {
public void foo() { /*does foo*/ }
...
}
public enum Models {
XML(new MyXMLModelDelgate()),
JSON(new MyJSONModelDelegate());
private Model delegate;
public Models(Model delegate) { this.delegate=delegate; }
public void foo() { delegate.foo(); }
}
You can use reflection. Something like this:
public interface Model {
class Singleton {
public static Model instance(Class<? extends Model> modelClass) {
try {
return (Model)modelClass.getField("instance").get(null);
} catch (blah-blah) {
blah-blah
}
}
}
public class XmlModel implements Model {
private static final Model instance = new XmlModel();
private XmlModel() {
}
}
usage:
Model.Singleton.instance(XmlModel.class)
Actually, I don't like this code much :). First, it uses reflection - very slow, second - there are possibilities of runtime errors in case of wrong definitions of classes.
Can you refactor the interface to be an abstract class? This will allow you to force a particular factory method down to all implementing classes.
I used to ask myself the same question. And I proposed the same answer ;-)
Now I normally drop the "forcing" behavior, I rely on documentation.
I found no case where the Singleton aspect was so compelling that it needed to be enforced by all means.
It is just a "best-practice" for the project.
I usually use Spring to instanciate such an object,
and it is the Spring configuration that makes it a Singleton.
Safe, and so easy ... plus additionnal Spring advantages (such as Proxying, substituing a different object once to make some tests etc...)
This is more an answer to your comment/clarification to kts's answer. Is it so, that the real problem is not using the Singleton pattern but instead defining an eclipse (equinox) extension point schema that allows contributing a singleton?
I think, this can't be done, because everytime you call IConfigurationElement.createExecutableExtension you create a new instance. This is quite incompatible with your singleton requirement. And therefore you need the public default constructor so that everybody can create instances.
Unless you can change the extension point definition so that plugins contribute a ModelFactory rather than a model, like
public interface ModelFactory {
public Model getModelInstance();
}
So the extension user will instantiate a ModelFactory and use it to obtain the singleton.
If I guessed wrong, leave a comment and I delete the answer ;)