How to modify an encapsulated library in Java? - java

I am using a generator for my project. Problem is now I need to modify this library's some methods according to my needs.
Generator class is final so I can't create a new class that extends it. Also putlast method is private.
Is there a way to solve this problem or I need to remove this library?
My main method;
generator.setFlowProperty(myProperty);
Library classes;
public final class Generator{
public Builder setFlowProperty(Property property) {
putLast("flowProperty", property.toCustomString());
....
}
private Builder putLast(String name, String value) {
....
}
}
public final class Property{
public String toCustomString(){
return "a" + prop; // I want to modify this and return "b"+ instead of "a"+.
}
}

There is no way you can inherit final class. I suppose library author made Generator class not for overriding. Anyway you can create your own class with logic you want.

If you want to override only a few functionalties of the library and leave most of them as they are, you can create a class that wraps the library class, only modifying the desired behaviours. So, the main purpose of this class will be to serve as a proxy before the library class, except when you want to modify some behaviour.

Related

How to correctly synchronize method access in Java

I have a class Library which is a third-part library that I don't have access to the source code. This class is used in different class of my project, such as
public class MyOwnClass1 {
private Library lib;
public void doTask () {
String res = lib.libMethod1();
... ... ...
}
}
However, it turns out that the class Library is not thread-safe, for instance, when the method libMethod1 is called simultaneously in different threads, it causes weird problems.
Thus, I have to implement my own thread-safe mechanisms, the 1st one is to encapsulate the Library variable into an other class.
public class SafeLibrary {
private Library lib;
private Object mutex = new Object();
... ... ...
public String doTask () {
synchronized(this.mutex) {
return this.lib.libMethod1();
}
}
... ... ...
}
But as I said, the Library class is used in different methods of different class. If I have to place all the related method into the new SafeLibrary class, it will cost a lot of code modification.
So Here is the 2nd idea:
public class SafeLibrary {
private Library lib;
private Object mutex = new Object();
public Object getMutex() {
return this.mutex;
}
public Library getLib() {
return this.lib;
}
}
Then I synchronize the method access in my own class:
public class MyOwnClass1 {
private SafeLibrary lib;
public void doTask () {
synchronized(lib.getMutext()) {
String res = lib.getLib().libMethod1();
... ... ...
}
}
}
By using the 2nd solution, I only have to do some small modifications in related methods. But the getMutex() seems an improper way to go.
I'd like to know which solution is correct, or if there is a an other better solution ? Thanks.
If Library and the methods you want to use are not final, and you create the library object yourself (rather than getting it from a static method of Library itself), then you can create your own class:
public class SynchronizedLibrary extends Library {
public synchronized String libMethod1() {
super.libMethod1();
}
}
Then all you have to do is replace the constructor calls, and can even leave the declared type as plain old Library (although you may not want to).
You have two options, you can either synchronize your class or synchronize a particular methods. What you did with was synchronize a class. Here's an example on synchronizing a class:
https://docs.oracle.com/javase/tutorial/essential/concurrency/syncrgb.html
Here's an example of synchronizing a method:
https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
Basically just add the word "synchronized" after the "public" and before the return value. Think of it like adding "final" to a method.
The best solution will depend on your software architecture. If it's just that one method you are worried about and that method is a characteristic of the object you are creating, then just synchronize the method. If you're creating an independent object that other objects/threads need, then synchronize the object.

How to read a variable from an abstract class?

is it posible to read the "worldInfo" from another class ?
the following is part of the class that holds it:
public abstract class World implements IBlockAccess{
protected WorldInfo worldInfo;
//=====Stuff=====
public World(ISaveHandler par1ISaveHandler, String par2Str, WorldSettings par3WorldSettings, WorldProvider par4WorldProvider, Profiler par5Profiler, ILogAgent par6ILogAgent)
{
this.worldInfo.setWorldName(par2Str);
}
}
i want to use it in my class to get the name. "worldInfo.getWorldName"
EDIT 1:
Ok i created a class in the same package with the World.. "World_Spy.class"
public class World_Spy extends World{
public World_Spy(ISaveHandler par1iSaveHandler, String par2Str,
WorldProvider par3WorldProvider, WorldSettings par4WorldSettings,
Profiler par5Profiler, ILogAgent par6iLogAgent) {
super(par1iSaveHandler, par2Str, par3WorldProvider, par4WorldSettings,
par5Profiler, par6iLogAgent);
}
#Override
protected IChunkProvider createChunkProvider() {
return null;
}
#Override
public Entity getEntityByID(int i) {
return null;
}
String TheName = "";
public void gotIt(){
TheName = this.worldInfo.getWorldName();
System.out.println(TheName);
}
}
But when i call it from the main class it crashes the game..
World_Spy WName = new World_Spy(null, null, null, null, null, null);
Is it about the parameters?
In order to access worldInfo you'll have to extend World but as worldName is set to the second parameter of World constructor, it means you have to know it in your child class, so ..
For the functionality you want, either change the keyword protected to public, or create a public function in the class. It would look something like this:
public String getWorldName(){
this.worldInfo.getWorldName();
}
Actually, protected means it can be used by childclasses but also by any other class in the same package. So yes, you can use it by all classes in the same package even if they're not subclassing the abstract class
The class is abstract, so it cannot be initiated. You can read static variables from this class, but you cannot create object of this class. You can make this variabale as static and then you read it or inherit this class and make object of it or make it non-abstract and make object of it.
This variable holds constant? Make it static.
The field can be accessed directly if one of the following is true:
That another class extends World (inherited protected fields are
visible in derived classes, also World is not final and has non private constructor)
That another class belongs to the same package (protected fields are
visible in classes from the same package, same as package private).
The field can also be accessed through reflection from any other class after setting accessible property to true on that field (as long as security manager permits).

Get name of class during static construction

In C# I can assign the name of a class to a local static variable like this.
public class MyClass
{
private static string TAG = typeof(MyClass).Name;
}
I've found this very useful, because the value of the string automatically updated if the class is refactored to another name. Handy for tagging debug messages and such.
Is something like this possible in Java?
public class MyClass
{
private static String TAG = ????;
}
I know I could use getClass().getName() but that requires a reference to an object. Is there a way to do this on a static variable?
You don't need to assign the name of a class to field instead of writing.
MyClass.TAG
you can write
MyClass.class.getName();
If you really need to you can assign this to TAG but I don't see the point.
A trick is also available that does not require programmer's knowledge of the class name beforehand:
public class MyClass
{
private static String TAG =
new Object() { }.getClass().getEnclosingClass().getName();
}
This trick uses a nested anonymous Object subclass to get hold of the execution context. It has a benefit of being copy/paste safe in case of cloning your code across different classes...

Simulate static abstract and dynamic linking on static method call in Java

Introduction
As a disclaimer, I'v read Why can't static methods be abstract in Java and, even if I respectfully disagree with the accepted answer about a "logical contradiction", I don't want any answer about the usefulness of static abstract just an answer to my question ;)
I have a class hierarchy representing some tables from a database. Each class inherits the Entity class which contains a lot of utility methods for accessing the database, creating queries, escaping characters, etc.
Each instance of a class is a row from the database.
The problem
Now, in order to factorize as much code as possible, I want to add information about related columns and table name for each class. These informations must be accessible without a class instance and will be used in Entity to build queries among other things.
The obvious way to store these data are static fields returned by static methods in each class. Problem is you can't force the class to implement these static methods and you can't do dynamic linking on static methods call in Java.
My Solutions
Use a HashMap, or any similar data structure, to hold the informations. Problem : if informations are missing error will be at runtime not compile time.
Use a parallel class hierarchy for the utility function where each corresponding class can be instantiated and dynamic linking used. Problem : code heavy, runtime error if the class don't exist
The question
How will you cope with the absence of abstract static and dynamic linking on abstract method ?
In a perfect world, the given solution should generate a compile error if the informations for a class are missing and data should be easily accessible from withing the Entity class.
The answer doesn't need to be in Java, C# is also ok and any insight on how to do this without some specific code in any language will be welcomed.
Just to be clear, I don't have any requirement at all besides simplicity. Nothing have to be static. I only want to retrieve table and columns name from Entity to build a query.
Some code
class Entity {
public static function afunction(Class clazz) { // this parameter is an option
// here I need to have access to table name of any children of Entity
}
}
class A extends Entity {
static String table = "a";
}
class B extends Entity {
static String table = "b";
}
You should use the Java annotation coupled with the javac annotation processor, as it's the most efficient solution. It's however a bit more complicated than the usual annotation paradigm.
This link shows you how you can implement an annotation processor that will be used at the compile time.
If I reuse your example, I'd go this way:
#Target(ElementType.TYPE)
#Retention(RetentionType.SOURCE)
#interface MetaData {
String table();
}
abstract class Entity {}
#MetaData(table="a")
class A extends Entity {}
#MetaData(table="b")
class B extends Entity {}
class EntityGetter {
public <E extends Entity> E getEntity(Class<E> type) {
MetaData metaData = type.getAnnotation(MetaData.class);
if (metaData == null) {
throw new Error("Should have been compiled with the preprocessor.");
// Yes, do throw an Error. It's a compile-time error, not a simple exceptional condition.
}
String table = metaData.table();
// do whatever you need.
}
}
In your annotation processing, you then should check whether the annotation is set, whether the values are correct, and make the compilation fail.
The complete documentation is available in the documentation for the package javax.annotation.processing.
Also, a few tutorials are available on the Internet if you search for "java annotation processing".
I will not go deeper in the subject as I never used the technology myself before.
I have run into the same problems as you, and am using the following approach now. Store Metadata about columns as annotations and parse them at runtime. Store this information in a map. If you really want compile time errors to appear, most IDEs (Eclipse e.g.) support custom builder types, that can validate the classes during build time.
You could also use the compile time annotation processing tool which comes with java, which can also be integrated into the IDE builds. Read into it and give it a try.
In Java the most similar approach to "static classes" are the static enums.
The enum elements are handed as static constants, so they can be accesed from any static context.
The enum can define one or more private constructors, accepting some intialization parameters (as it could be a table name, a set of columns, etc).
The enum class can define abstract methods, which must be implemented by the concrete elements, in order to compile.
public enum EntityMetadata {
TABLE_A("TableA", new String[]{"ID", "DESC"}) {
#Override
public void doSomethingWeirdAndExclusive() {
Logger.getLogger(getTableName()).info("I'm positively TableA Metadata");
}
},
TABLE_B("TableB", new String[]{"ID", "AMOUNT", "CURRENCY"}) {
#Override
public void doSomethingWeirdAndExclusive() {
Logger.getLogger(getTableName()).info("FOO BAR message, or whatever");
}
};
private String tableName;
private String[] columnNames;
private EntityMetadata(String aTableName, String[] someColumnNames) {
tableName=aTableName;
columnNames=someColumnNames;
}
public String getTableName() {
return tableName;
}
public String[] getColumnNames() {
return columnNames;
}
public abstract void doSomethingWeirdAndExclusive();
}
Then to access a concrete entity metadata this would be enough:
EntityMetadata.TABLE_B.doSomethingWeirdAndExclusive();
You could also reference them from an Entity implemetation, forcing each to refer an EntityMetadata element:
abstract class Entity {
public abstract EntityMetadata getMetadata();
}
class A extends Entity {
public EntityMetadata getMetadata() {
return EntityMetadata.TABLE_A;
}
}
class B extends Entity {
public EntityMetadata getMetadata() {
return EntityMetadata.TABLE_B;
}
}
IMO, this approach will be fast and light-weight.
The dark side of it is that if your enum type needs to be really complex, with lot of different params, or a few different complex overriden methods, the source code for the enum can become a little messy.
Mi idea, is to skip the tables stuff, and relate to the "There are not abstract static methods". Use "pseudo-abstract-static" methods.
First define an exception that will ocurr when an abstract static method is executed:
public class StaticAbstractCallException extends Exception {
StaticAbstractCallException (String strMessage){
super(strMessage);
}
public String toString(){
return "StaticAbstractCallException";
}
} // class
An "abstract" method means it will be overriden in subclasses, so you may want to define a base class, with static methods that are suppouse to be "abstract".
abstract class MyDynamicDevice {
public static void start() {
throw new StaticAbstractCallException("MyDynamicDevice.start()");
}
public static void doSomething() {
throw new StaticAbstractCallException("MyDynamicDevice.doSomething()");
}
public static void finish() {
throw new StaticAbstractCallException("MyDynamicDevice.finish()");
}
// other "abstract" static methods
} // class
...
And finally, define the subclasses that override the "pseudo-abstract" methods.
class myPrinterBrandDevice extends MyDynamicDevice {
public static void start() {
// override MyStaticLibrary.start()
}
/*
// ops, we forgot to override this method !!!
public static void doSomething() {
// ...
}
*/
public static void finish() {
// override MyStaticLibrary.finish()
}
// other abstract static methods
} // class
When the static myStringLibrary doSomething is called, an exception will be generated.
I do know of a solution providing all you want, but it's a huge hack I wouldn't want in my own code nowadays:
If Entity may be abstract, simply add your methods providing the meta data to that base class and declare them abstract.
Otherwise create an interface, with methods providing all your data like this
public interface EntityMetaData{
public String getTableName();
...
}
All subclasses of Entity would have to implement this interface though.
Now your problem is to call these methods from your static utility method, since you don't have an instance there. So you need to create an instance. Using Class.newInstance() is not feasable, since you'd need a nullary constructor, and there might be expensive initialization or initialization with side-effects happening in the constructor, you don't want to trigger.
The hack I propose is to use Objenesis to instantiate your Class. This library allows instatiating any class, without calling the constructor. There's no need for a nullary constructor either. They do this with some huge hacks internally, which are adapted for all major JVMs.
So your code would look like this:
public static function afunction(Class clazz) {
Objenesis objenesis = new ObjenesisStd();
ObjectInstantiator instantiator = objenesis.getInstantiatorOf(clazz);
Entity entity = (Entity)instantiator.newInstance();
// use it
String tableName = entity.getTableName();
...
}
Obviously you should cache your instances using a Map<Class,Entity>, which reduces the runtime cost to practically nothing (a single lookup in your caching map).
I am using Objenesis in one project of my own, where it enabled me to create a beautiful, fluent API. That was such a big win for me, that I put up with this hack. So I can tell you, that it really works. I used my library in many environments with many different JVM versions.
But this is not good design! I advise against using such a hack, even if it works for now, it might stop in the next JVM. And then you'll have to pray for an update of Objenesis...
If I were you, I'd rethink my design leading to the whole requirement. Or give up compile time checking and use annotations.
Your requirement to have static method doesn't leave much space for clean solution. One of the possible ways is to mix static and dynamic, and lose some CPU for a price of saving on RAM:
class Entity {
private static final ConcurrentMap<Class, EntityMetadata> metadataMap = new ...;
Entity(EntityMetadata entityMetadata) {
metadataMap.putIfAbsent(getClass(), entityMetadata);
}
public static EntityMetadata getMetadata(Class clazz) {
return metadataMap.get(clazz);
}
}
The way I would like more would be to waste a reference but have it dynamic:
class Entity {
protected final EntityMetadata entityMetadata;
public Entity(EntityMetadata entityMetadata) {
this.entityMetadata=entityMetadata;
}
}
class A extends Entity {
static {
MetadataFactory.setMetadataFor(A.class, ...);
}
public A() {
super(MetadataFactory.getMetadataFor(A.class));
}
}
class MetadataFactory {
public static EntityMetadata getMetadataFor(Class clazz) {
return ...;
}
public static void setMetadataFor(Class clazz, EntityMetadata metadata) {
...;
}
}
You could get even get rid of EntityMetadata in Entity completely and leave it factory only. Yes, it would not force to provide it for each class in compile-time, but you can easily enforce that in the runtime. Compile-time errors are great but they aren't holy cows after all as you'd always get an error immediately if a class hasn't provided a relevant metadata part.
I would have abstracted away all meta data for the entities (table names, column names) to a service not known by the entities them selfs. Would be much cleaner than having that information inside the entities
MetaData md = metadataProvider.GetMetaData<T>();
String tableName = md.getTableName();
First, let me tell you I agree with you I would like to have a way to enforce static method to be present in classes.
As a solution you can "extend" compile time by using a custom ANT task that checks for the presence of such methods, and get error in compilation time. Of course it won't help you inside you IDE, but you can use a customizable static code analyzer like PMD and create a custom rule to check for the same thing.
And there you java compile (well, almost compile) and edit time error checking.
The dynamic linking emulation...well, this is harder. I'm not sure I understand what you mean. Can you write an example of what you expect to happen?

Design pattern to handle settings in subclasses?

I have a small hierarchy of classes that all implement a common interface.
Each of the concrete class needs to receive a settings structure containing for instance only public fields. The problem is that the setting structure
has a part common to all classes
has another part that vary from one concrete class to another
I was wondering if you had in your mind any elegant design to handle this. I would like to build something like:
BaseFunc doer = new ConcreteImplementation1();
with ConcreteImplementation1 implements BaseFunc. And have something like
doer.setSettings(settings)
but have the ''settings'' object having a concrete implementation that would be suitable to ConcreteImplementation1.
How would you do that?
This may be a named design pattern, if it is, I don't know the name.
Declare an abstract class that implements the desired interface. The abstract class constructor should take an instance of your settings object from which it will extract the global settings. Derive one or more classes from the abstract class. The derived class constructor should take an instance of your settings object, pass it to the parent class constructor, then extract any local settings.
Below is an example:
class AbstractThing implements DesiredInterface
{
private String globalSettingValue1;
private String globalSettingValue2;
protected AbstractThing(Settings settings)
{
globalSettingValue1 = settings.getGlobalSettingsValue1();
globalSettingValue2 = settings.getGlobalSettingsValue2();
}
protected String getGlobalSettingValue1()
{
return globalSettingValue1;
}
protected String getGlobalSettingValue2()
{
return globalSettingValue2;
}
}
class DerivedThing extends AbstractThing
{
private String derivedThingSettingValue1;
private String derivedThingSettingValue2;
public DerivedThing(Settings settings)
{
super(settings);
derivedThingSettingValue1 = settings.getDerivedThingSettingsValue1();
derivedThingSettingValue2 = settings.getDerivedThingSettingsValue2();
}
}
Have a matching hierarchy of settings objects, use Factory to create the settings that match a specific class.
Sounds like you need a pretty standard Visitor pattern.
To put it simple, suppose, that all your properties are stored as key-value pairs in maps. And you have 3 classes in your hierarchy: A, B, C. They all implement some common interface CI.
Then you need to create a property holder like this:
public class PropertyHolder {
public Map<String, String> getCommonProperties () { ... }
public Map<String, String> getSpecialPropertiesFor (CI a) { return EMPTY_MAP; }
public Map<String, String> getSpecialPropertiesFor (A a) { ... }
public Map<String, String> getSpecialPropertiesFor (B b) { ... }
...
}
All your classes should implement 1 method getSpecialProperties which is declared in the interface CI. The implementation as simple as:
public Map<String, String> getSpecialProperties (PropertyHolder holder) {
return holder.getSpecialPropertiesFor (this);
}
I went down this route once. It worked, but after decided it wasn't worth it.
You can define a base class MyBean or something, and it has its own mergeSettings method. Every class you want to use this framework can extend MyBean, and provide its own implementation for mergeSettings which calls the superclasses mergeSettings. That way the common fields can be on the super class. If you want to get really fancy you can define and interface and abstract class to really make it pretty. And while your at it, maybe you could use reflection. anyway, mergeSettings would take a Map where the key is the property name. Each class would have its constants to related to the keys.
class MyBean extends AbstractMyBean ... {
public static final String FIELD1 = 'field1'
private String field1
public mergeSettings(Map<String, Object> incoming) {
this.field1 = incoming.get(FIELD1);
// and so on, also do validation here....maybe put it on the abstract class
}
}
Its a lot of work for setters though...
I started toying with a new pattern that I called "type-safe object map". It's like a Java Map but the values have type. That allows you to define the keys that each class wants to read and get the values in a type safe way (with no run-time cost!)
See my blog for details.
The nice thing about this is that it's still a map, so you can easily implement inheritance, notification, etc.
You could use Generics to define what kind of settings this instance need. Something like this:
public abstract class MySuperClass<T extends MySettingsGenericType>{
public MySuperClass(T settings){
//get your generic params here
}
}
public class MyEspecificClass extends MySuperClass<T extends MySettingsForThisType>{
public MySuperClass(T settings){
super(settings);
//Get your espefic params here.
}
}
//and you could use this
BaseFunc doer = new ConcreteImplementation1(ConcreteSettingsFor1);
//I dont compile this code and write in a rush. Sorry if have some error...

Categories

Resources