How to configure Eclipse debugging and hotswap for JBoss and WebLogic
Excerpt:
Lastly, tell Eclipse not to erase other files in the output folder every time it builds the project. While still in Preferences navigate to Java | Compiler | Building and uncheck Scrub output folders when cleaning projects. That's it. Now every time you save a Java file, Eclipse will recompile it and JBoss will reload it.
WebLogic hot swap
Terracotta vs. Hibernate
After a side-by-side implementation comparison, where ACID Transactions and persistence were not strictly required, utilizing Terracotta required ~1/4 the LOC implementation of a Hibernate implementation. Terracotta required ~5 implementaion files vs. ~14 implementation files for Hibernate - several were related to DDL. Hibernate required DDL, mapping files or annotations, DAOs, dbUnit test data, and integration tests. Terracotta required POJOs and plain unit tests instead of the integration tests necessary for Hibernate.
To avoid surprises, it is generally good practice to thoroughly test all Hibernate mappings and test against the target database.
Also significant, is the fact that the Terracotta implementation doesn't unnecessarily tax the least scalable component of the system; the database.
To avoid surprises, it is generally good practice to thoroughly test all Hibernate mappings and test against the target database.
Also significant, is the fact that the Terracotta implementation doesn't unnecessarily tax the least scalable component of the system; the database.
Remote windows shutdown/restart
c:> shutdown -?
c:> shutdown -r -f -m \\<Computer> -t 1 -c "some message"
Restart in 1 second forcing applications to close
c:> shutdown -r -f -m \\<Computer> -t 1 -c "some message"
Restart in 1 second forcing applications to close
Windows Tools
RKTools - alternative to cygwin
TCPView - Sysinternals
Windows Telnet server
Telnet client - Java Applet The Java Telnet Application
TCPView - Sysinternals
Windows Telnet server
Telnet client - Java Applet The Java Telnet Application
Favor composition over inheritance
I have take Josh Bloch’s recommendations to heart:
• Item 15 minimize mutability
• Item 16 favor composition over inheritance
• Close/limit the API as much as possible and open/expose it only as necessary
• Design for inheritance and document it or disallow it
I have created very few class inheritance hierarchies over the years – except when I was heavily doing swing/UI work. I used to create lots of abstract classes for common behavior; however, I have since switched to creating interface inheritance hierarchies and utilizing composition. While it is slightly more work except for testing, I can’t recall any particular situation where composition hasn’t worked. However, there are certainly situations where a class inheritance hierarchy is more ideal and I would still favor it over composition.
I have specifically found composition to be excellent for TDD. I can test the parent class fully. Later when I compose, I use a mock and just test the pass-through methods and the new behavior.
If extension were utilized and the parent properties were exposed (broken encapsulation) and utilized, it becomes necessary to inspect the parent and test everything that the extension class touches that is related in any way. If you don’t thoroughly test the extension and someone alters the parent class or some sub-class of the extension, the direct sub-classes very well may break because of the assumptions about the parent class’s behavior with respect to the broken encapsulation. Of course if you break your own encapsulation with getters/setters, which unfortunately is often the case, you gain little or no safety through composition.
I also put final everywhere possible. I prefer to remove final only when I have a very good reason.
If you are ever bored, here is an article on Encapsulation and Inheritance which discusses some of the evils.
• Item 15 minimize mutability
• Item 16 favor composition over inheritance
• Close/limit the API as much as possible and open/expose it only as necessary
• Design for inheritance and document it or disallow it
I have created very few class inheritance hierarchies over the years – except when I was heavily doing swing/UI work. I used to create lots of abstract classes for common behavior; however, I have since switched to creating interface inheritance hierarchies and utilizing composition. While it is slightly more work except for testing, I can’t recall any particular situation where composition hasn’t worked. However, there are certainly situations where a class inheritance hierarchy is more ideal and I would still favor it over composition.
I have specifically found composition to be excellent for TDD. I can test the parent class fully. Later when I compose, I use a mock and just test the pass-through methods and the new behavior.
If extension were utilized and the parent properties were exposed (broken encapsulation) and utilized, it becomes necessary to inspect the parent and test everything that the extension class touches that is related in any way. If you don’t thoroughly test the extension and someone alters the parent class or some sub-class of the extension, the direct sub-classes very well may break because of the assumptions about the parent class’s behavior with respect to the broken encapsulation. Of course if you break your own encapsulation with getters/setters, which unfortunately is often the case, you gain little or no safety through composition.
I also put final everywhere possible. I prefer to remove final only when I have a very good reason.
If you are ever bored, here is an article on Encapsulation and Inheritance which discusses some of the evils.
Exception best practices
Favor RuntimeExceptions over checked exceptions – follow Hibernate’s example. This allows clients to choose what to do.
Always declare throws on methods even for runtime exceptions - for clarity, not necessary in tests
Always include @throws in the JavaDoc for each exception and state under what circumstances it throws the exceptions
Always include the details (state) related to the cause of the exception in the message - this will help others debug the issue (it isn’t really for us the developers, it’s for the poor guys/gals on the front line who have to debug our broken s$*t) – utilize String.format and include what was being processed and all state that might be helpful in understanding the issue – beware of possible NPEs in String.format arg method calls. And yes this takes time and requires thought on how to clearly convey the information; however it is incredibly useful, sometimes even for us developers.
Always remember to wrap any source exceptions in your own exception processing.
In worker threads – generally catch, log, convey (if necessary), and swallow all exceptions – generally you don’t want your worker threads terminating as they are often loops which will have additional work to process
In loops consider if you should aggregate exceptions and continue processing – do you really want to stop after an exception or process as much as possible collecting the exceptional issues to be returned later as a set
Always declare throws on methods even for runtime exceptions - for clarity, not necessary in tests
Always include @throws in the JavaDoc for each exception and state under what circumstances it throws the exceptions
Always include the details (state) related to the cause of the exception in the message - this will help others debug the issue (it isn’t really for us the developers, it’s for the poor guys/gals on the front line who have to debug our broken s$*t) – utilize String.format and include what was being processed and all state that might be helpful in understanding the issue – beware of possible NPEs in String.format arg method calls. And yes this takes time and requires thought on how to clearly convey the information; however it is incredibly useful, sometimes even for us developers.
Always remember to wrap any source exceptions in your own exception processing.
In worker threads – generally catch, log, convey (if necessary), and swallow all exceptions – generally you don’t want your worker threads terminating as they are often loops which will have additional work to process
In loops consider if you should aggregate exceptions and continue processing – do you really want to stop after an exception or process as much as possible collecting the exceptional issues to be returned later as a set
Use final modifer liberally
The Final Word on the Final Modifier
Using final:
• Prevents bugs
• Ensures thread-safety
• Ensures security
• Generally improves performance
• Enforces better design/implementation - favoring composition over inheritance
Final modifier
Using final:
• Prevents bugs
• Ensures thread-safety
• Ensures security
• Generally improves performance
• Enforces better design/implementation - favoring composition over inheritance
Final modifier
Windows Loopback adapter for Oracle
URI
URI
URI scheme
URI uri = new URI("schemaElement://pathElement@hostName:1234/pathElement?queryElement#fragmentElement");
System.out.println("getAuthority=" + uri.getAuthority());
System.out.println("getFragment=" + uri.getFragment());
System.out.println("getHost=" + uri.getHost());
System.out.println("getPath=" + uri.getPath());
System.out.println("getPort=" + uri.getPort());
System.out.println("getQuery=" + uri.getQuery());
System.out.println("getScheme=" + uri.getScheme());
System.out.println("getSchemeSpecificPart=" + uri.getSchemeSpecificPart());
Console output:
getAuthority=pathElement@hostName:1234
getFragment=fragmentElement
getHost=hostName
getPath=/pathElement
getPort=1234
getQuery=queryElement
getScheme=schemaElement
getSchemeSpecificPart=//pathElement@hostName:1234/pathElement?queryElement
URI scheme
URI uri = new URI("schemaElement://pathElement@hostName:1234/pathElement?queryElement#fragmentElement");
System.out.println("getAuthority=" + uri.getAuthority());
System.out.println("getFragment=" + uri.getFragment());
System.out.println("getHost=" + uri.getHost());
System.out.println("getPath=" + uri.getPath());
System.out.println("getPort=" + uri.getPort());
System.out.println("getQuery=" + uri.getQuery());
System.out.println("getScheme=" + uri.getScheme());
System.out.println("getSchemeSpecificPart=" + uri.getSchemeSpecificPart());
Console output:
getAuthority=pathElement@hostName:1234
getFragment=fragmentElement
getHost=hostName
getPath=/pathElement
getPort=1234
getQuery=queryElement
getScheme=schemaElement
getSchemeSpecificPart=//pathElement@hostName:1234/pathElement?queryElement
Cloud Storage
Using Google App Engine and Google distributed BigTable storage
Amazon S3
S3 scaling, performance, and retries
hadoop
HBase Hadoop Database - BigTable
Google BigTable Webservice
Terracotta
Terracotta EhCache example
Nirvanix Storage Delivery Network
Mosso Rackspace
Sherpa - Yahoo Cloud Storage - CAP theorem
Yahoo Developer Network Blog
Notes on Distributed Keystores
MySQL
Project Voldemort
LightCloud
CouchDB
Tokyo Cabinet
Google BigTable:
One big difference between BigTable and relational databases is how transactions are handled. Row-level transactions are possible in BigTable, but not any other type of transactions.
The unsung hero of the day that really makes BigTable shine, however, is Chubby. Chubby is a lock-providing service that is highly available and allows many difficult design decisions to be abstracted away from BigTable. When a BigTable server (master or slave) comes up, it reserves a lock through Chubby with its name and path, and renews the lock periodically. This makes it trivial for the master to determine which nodes are up and down, as it can just query Chubby to see who has locks (thus these nodes are up). Since the BigTable master also knows the locations of the slaves, it can trivially determine if Chubby is down (it would be unable to see who has locks in Chubby but still be able to contact them).
Building a database on S3:
All protocols proposed in this work were designed to support a large number of concurrent clients; possibly in the thousands or even millions. It is assumed that the utility provider (i.e., S3) can support such a large number of clients and guarantees (pretty much) constant response times, independent of the number of concurrent clients. Furthermore, the utility provider guarantees a high degree of availability and durability; that is, clients can read and write pages from/to S3 at any moment in time without being blocked and updates are never lost by the utility provider. All these properties must be preserved in the application stack at the client. As a result, the protocols must be designed in such a way that any client can fail at any time without blocking any other client. That is, clients are never allowed to hold any locks that would block the execution at other clients. Furthermore, clients are stateless. They may cache data from S3, but the worst thing that can happen if a client fails is that all the work of that client is lost. Obviously, fulfilling all these requirements comes at a cost: eventual consistency [19]. That is, it might take a while before the updates of one client become visible at other clients. Furthermore, ANSI SQL-style isolation and serialization [3] are impossible to achieve under these requirements. Following [21], we believe that strict consistency and ACID transactions are not needed for most Web-based applications, whereas scalability and availability are a must.
S3 Integrity, Locking, and Transactions
S3 provides reliability and availability by replicating data to many servers that could be geographically dispersed. Although updates on a single key are atomic, only eventual consistency is guaranteed. Fetching a key’s value might return stale data. Additionally, S3 does not support neither locking nor multi-key atomic updates or transactions. These shortcomings could present obstacles for multi-user settings where key-value pairs on S3 might be constantly edited. Furthermore, S3 provides little tangible guarantees that data retrieved on a particular read faithfully corresponds to the last put operation on that key (data integrity).
To exemplify these problems, imagine a scenario where a company uses S3 to store internal files that are shared between multiple employees. Employees may retrieve and edit any number of files, some of which might also be editable by others. In order to maintain a serializable view
of the file system, users must ensure that they are dealing with the latest version of a file when modifying it. Serializability also requires the use of locks to prevent simultaneous conflicting updates to a single file. Furthermore, as for many modern file systems, transactions are necessary to group multiple updates and be able to rollback undesired outcomes. Multi-key locks and transactions are also necessary since a single file operation might span multiple key-value pairs for data and meta-data. Finally, file system users need the integrity of their data to be preserved.
Yahoo Sherpa - CAP Theorem
There is something called CAP theorem that imposes a "restriction" in all distributed systems. Using the simpler explanation offered by Mr. Negrin, the CAP theorem restrictions can be explained as follows.
"unavoidable trade-offs between consistency (all records are the same in all replicas), availability (all replicas can accept updates or inserts), and tolerance of network partitions (the system still functions when distributed replicas cannot talk to each other)."
In order to take care of the limitations imposed by the CAP theorem, Yahoo team has chosen the tradeoff to be between consistency and availability. They offer the users various options to choose between consistency and availability and then offer tools to minimize the impact of their choice on the other parameter.
Amazon S3
S3 scaling, performance, and retries
hadoop
HBase Hadoop Database - BigTable
Google BigTable Webservice
Terracotta
Terracotta EhCache example
Nirvanix Storage Delivery Network
Mosso Rackspace
Sherpa - Yahoo Cloud Storage - CAP theorem
Yahoo Developer Network Blog
Notes on Distributed Keystores
MySQL
Project Voldemort
LightCloud
CouchDB
Tokyo Cabinet
Google BigTable:
One big difference between BigTable and relational databases is how transactions are handled. Row-level transactions are possible in BigTable, but not any other type of transactions.
The unsung hero of the day that really makes BigTable shine, however, is Chubby. Chubby is a lock-providing service that is highly available and allows many difficult design decisions to be abstracted away from BigTable. When a BigTable server (master or slave) comes up, it reserves a lock through Chubby with its name and path, and renews the lock periodically. This makes it trivial for the master to determine which nodes are up and down, as it can just query Chubby to see who has locks (thus these nodes are up). Since the BigTable master also knows the locations of the slaves, it can trivially determine if Chubby is down (it would be unable to see who has locks in Chubby but still be able to contact them).
Building a database on S3:
All protocols proposed in this work were designed to support a large number of concurrent clients; possibly in the thousands or even millions. It is assumed that the utility provider (i.e., S3) can support such a large number of clients and guarantees (pretty much) constant response times, independent of the number of concurrent clients. Furthermore, the utility provider guarantees a high degree of availability and durability; that is, clients can read and write pages from/to S3 at any moment in time without being blocked and updates are never lost by the utility provider. All these properties must be preserved in the application stack at the client. As a result, the protocols must be designed in such a way that any client can fail at any time without blocking any other client. That is, clients are never allowed to hold any locks that would block the execution at other clients. Furthermore, clients are stateless. They may cache data from S3, but the worst thing that can happen if a client fails is that all the work of that client is lost. Obviously, fulfilling all these requirements comes at a cost: eventual consistency [19]. That is, it might take a while before the updates of one client become visible at other clients. Furthermore, ANSI SQL-style isolation and serialization [3] are impossible to achieve under these requirements. Following [21], we believe that strict consistency and ACID transactions are not needed for most Web-based applications, whereas scalability and availability are a must.
S3 Integrity, Locking, and Transactions
S3 provides reliability and availability by replicating data to many servers that could be geographically dispersed. Although updates on a single key are atomic, only eventual consistency is guaranteed. Fetching a key’s value might return stale data. Additionally, S3 does not support neither locking nor multi-key atomic updates or transactions. These shortcomings could present obstacles for multi-user settings where key-value pairs on S3 might be constantly edited. Furthermore, S3 provides little tangible guarantees that data retrieved on a particular read faithfully corresponds to the last put operation on that key (data integrity).
To exemplify these problems, imagine a scenario where a company uses S3 to store internal files that are shared between multiple employees. Employees may retrieve and edit any number of files, some of which might also be editable by others. In order to maintain a serializable view
of the file system, users must ensure that they are dealing with the latest version of a file when modifying it. Serializability also requires the use of locks to prevent simultaneous conflicting updates to a single file. Furthermore, as for many modern file systems, transactions are necessary to group multiple updates and be able to rollback undesired outcomes. Multi-key locks and transactions are also necessary since a single file operation might span multiple key-value pairs for data and meta-data. Finally, file system users need the integrity of their data to be preserved.
Yahoo Sherpa - CAP Theorem
There is something called CAP theorem that imposes a "restriction" in all distributed systems. Using the simpler explanation offered by Mr. Negrin, the CAP theorem restrictions can be explained as follows.
"unavoidable trade-offs between consistency (all records are the same in all replicas), availability (all replicas can accept updates or inserts), and tolerance of network partitions (the system still functions when distributed replicas cannot talk to each other)."
In order to take care of the limitations imposed by the CAP theorem, Yahoo team has chosen the tradeoff to be between consistency and availability. They offer the users various options to choose between consistency and availability and then offer tools to minimize the impact of their choice on the other parameter.
Subscribe to:
Posts (Atom)