Holy on Dev
Seam Tutorial 1.2: RichFaces and paged table (datascroller)
In this two-part tutorial you will learn how to get started with the development of Seam applications with RichFaces using Eclipse with JBoss Tools. In the 1st part we've set up our environment, created, and run an empty shell Seam application. In this 2nd part we will create a simple web page with a table presenting data on multiple pages using Ajax (a RichFaces component) and its model stored as a POJO Component in the Seam Conversation scope. I assume that you already have some basic knowledge of Seam and JSF, for instance that you know what a Component or the Conversation scope are. I'll present my path to this goal with all the mistakes so that you too can learn from them.
My aim in this tutorial series is to create a Seam portlet displaying data in a paged (and ideally also sortable and filterable, but lets be realistic) table running in the Liferay portal.
The Forgotten Hells or God Save North Korea!
I intended this as an exclusively technological blog but after seeing the movie Yodok Stories yesterday I feel I can't keep silent on the subject. I'm even more touched by the movie because the first years of my life I spent myself in a communist dictatorship though it was already in its last stage and can be by no means compared to the nightmare of Korea. On this planet there are hellish places where human life or dignity have no value,
When will we see JSR 286 in JSF portlets?
Since June 2008 we have the final release of Portlet 2.0 (JSR 286) specification bringing the long sought after features like inter-portlet communication (IPC - events, shared/public render parameters), support for Ajax (resource request), portlet filters and more. It's already implemented in the latest versions of leading portals including Liferay 5.0, JBoss 2.7, Websphere 6.1 (though you can still encounter some bugs). Now we would l
Seam Tutorial 1.1: RichFaces and paged table (datascroller)
In this two-part tutorial you will learn how to get started with the development of Seam applications with RichFaces using Eclipse with JBoss Tools. In the 2nd part we will create a simple page with a table presenting data on multiple pages using Ajax and its model stored as a POJO Component in the Seam Conversation scope. I assume that you already have some basic knowledge of Seam and JSF, for instance that you know what a Component or the Conversation scope are.
JSF: NullPointerException at FacesServlet.init line 144 / Can''t parse faces-config.xml - SocketException
Problem When deploying JSF 1.1 application to WebSphere 6.0 I got the following not much helpful exception: java.lang.NullPointerException at javax.faces.webapp.FacesServlet.init(FacesServlet.java:144)Checking SystemErr.log revealed the following explanation: javax.faces.FacesException: Can't parse configuration file:file:/usr/WebSphere/AppServer/profiles/profileNode1/installedApps/a25ciwas005Network/jholy-GroovyConsole
Are portlets dead? JSR168 and JSR286 versus reality.
Eric Spiegelberg, an experienced JEE and portlet developer, evaluates in his article JSR-286: The Edge of Irrelevance the changes brought to the portlet community by the "new" JSR 286 and comes to the sad conclusion that the portlet technology has missed its chance and is declining in interest and momentum and JSR 286 won't change that. Only rarely do the benefits of this technology outweigh
Eclipse 3.4: New Update Manager and broken Extension Locations
In Eclipse prior to 3.4 you could have a number of external "Extension Locations" for plugins/features you didn't want in the Eclipse installation directory or that you wanted to share among multiple Eclipse installations. In the Update Manager wizard you could have even selected that you want a plugin installed into a particular extension location. Since Eclipse 3.4 (Ganymede) this isn't possible anymore.Problem 1: Links to the external Extension Locations are ignored<
Webapp performance monitoring with Glassbox 2.0: How does it work?
A word of warning: Information on this page originates from my exploration of Glassbox performed in Oct 2008 and may be inaccurate. Ron Bodkin, the mastermind behind Glassbox, was so kind as to review this but still there may be some mistakes or inexact informatiom left. In any case blame me :-)
There're a few open source java webapp monitoring tools: Glassbox (latest release 2008-09-02), JAMon (2007-09-20), InfraRED (2006-05-17), UseMon (2008-10-06). Among these, Glassbox is both still actively developed and mature. It has also nice though only basic user documentation. Unfortunately there is only little docs about its architecture and about customizing it for monitoring a specific webapp. Therefore I've decided to dive into its code to learn more about it to be able to decide whether it's suitable for our needs of monitoring the Pentaho BI Platform web application.
The unique features of Glassbox are that it tries to point out existing performance problems together with their likely causes and advices what to do about them and that it displays aggregated statistics about the high level "operations" in the monitored web app.
Basic Info about Glassbox
Glassbox consists of a webapp UI that displays statistics and of a set of monitors that are injected into the observed webapp and collect data about its performance. Some of its characteristics are:
- Simple installation (1.Deploy webapp; 2. Run postinstall script to copy jars etc.; 3. Restart AS with a command-line option to load glassbox aspects).
- AOP using AspectJ.
- Preferably Java 5+ though it's also possible to use AspectJ with Java 1.4 and maybe 1.3.
- Data not persistent (though this is on the roadmap).
- Layer aware (UI, logic - EJB, resources - DB, I/O, ...).
- Customized monitors for popular frameworks (Spring MVC, ...).
- UI concentrates on providing the right information at the right time with the necessary context. In other words it doesn't display tons of detailed data but a list of top-level operations highlighting the problematic (slow/failing) ones and providing detailes on likely cause(s) of the problems.
How it works
- Aspect (wiki): There're many definitions, for us this is a piece of code injected into the monitored application to perform the actual monitoring of a particular method in a particular class.
- Components and resources: Glassbox breaks time spent in an operation down by the type of activity that consumed it distinguishing between 'components' such as database access or remote calls and 'resources' such as running java code, running native code, or thread waiting (usually I/O).
- Layer: A monitored method can belong to one of application's layers of processing such as ui.controller or resource.database.statement.
- Monitored method: Glassbox collect performance statistics only for selected important methods, for instance JDBC calls.
- Operation: An "entry point" of user requests into the application. Usually this is some high-level method such as a Struts Action's execute or JSP's service. Glassbox uses operations as the unit of monitoring service level agreements (SLA) and to analyze where time goes. Anything that's used within an operation is considered a resource (EJB call, DB query...). (Though the notion of components shall be added in the future.)
- In the source code, the classes having Operation in their name are often also used to track monitored methods.
- Request: a) Vaguely synonymous to a monitored method; b) In this text it often means a user-invoked request that resulted in some activity in the monitored web application (though I try to use the term user request to distinguish it from a) ).
Glassbox doesn't bother to monitor all methods that are invoked as a result of user request because it is not necessary and would incur higher overhead. It only monitors some especially significant methods of the call tree such as a Struts Action invocation or invocation of a data access method (being it simple JDBC or Hibernate). I call them "monitored methods", while in Glassbox' terms they are either operations (the top-level ones) or resource/component request.
The framework is aware of and takes care of tracking the hierarchy of monitored methods invoked during a single user request processing. This basically means that a monitored method may have a parent monitored method and that Glassbox stores both the aggregated duration of the higher level method and that of the nested one. For example, a JDBC executeQuery may be invoked from an EJB call, which is itself invoked from a Struts Action processing. Thus it can tell which processing layer or component/resource caused a particular top-level operation to be slow.
Glassbox is also aware of layers and monitored methods may be marked as belonging to a particular layer, e.g. the JDBC executeQuery would belong to the layer resource.database.statement.
Main components' behavior explained
The main parts of Glassbox are:
Pieces of code collecting detailed performance measurements of monitored methods. Usually they're implemented as aspects extending the glassbox framework,
which are injected (woven) into the monitored webapp instance. But sometimes Glassbox uses also e.g. filters, listeners, callbacks, and timer tasks.
Handle communication between the monitors and a client. In a
clustered environment, a separate instance is on each server.
- Client: Collects monitoring data from agents and displays
an aggregated view to a user. The most used one is the Glassbox web application but you can also use e.g. jconsole or implement another client. Usually you have only one client even in a clustered environment.
Monitors are mostly aspects injected into a monitored web application or the related code. Usually a monitor observes one or few methods in a single class. When one of the method is invoked, it creates a Response object storing the details of the invocation (its id, parameters, ...) and, once it finishes, its performance data. If the method has been invoked as a part of processing of another monitored method, its Response will have the Response object of that method as its parent, in other words monitored methods can be (even indirectly) nested and this structure is preserved in the monitoring data structures. A typical example is a servlet calling an EJB doing some JDBC stuff.
Responses are stored in a ThreadLocal stack, which makes it possible to really connect those Responses belonging to the processing of a single request, and once the top-level operation completes it can be considered as finished.
There is one agent per server (i.e. JVM). It collects the detailed monitoring data from monitors and aggregates them by monitored method into "statistics" (Stats) objects. Stats contain summarized data for a monitored method over all of its execution (avg, min, max time...) together with detailed data for a limited number of those executions that were either slow or failed. There are statistics both for top-level monitored methods and for nested ones and they're aware of each other. These stats are stored in a global StatisticsRegistry (namely OperationTracker's registry).
There is also a special background job (ThreadMonitor) that monitors threads to detect CPU-intensive methods. This is done by taking snapshots of the thread stack in regular intervals and - if its execution time exceeds a predefined limit - by drawing a conclusion from these snapshots. (Note: This is an example of a timer task monitor.)
The Glassbox web user interface queries all registered agents for their data (see OperationsHelper.updateListOfOperations). The detailed and hierarchical statistics are turned into an OperationSummary for the top-level operation having also a list of "findings", i.e. textual descriptions of problems with the operation. It contains average statistics and stats when slow and when failing.
Main components' behavior in detail
To monitor a web application, Glassbox inserts monitoring aspects into its code and related server code (e.g. its javax.servlet.Servlet implementation) during server startup using AspectJ. In its simplest form an aspect is nothing more than an XML file mapping an existing aspect class to a method(s) of a particular class.
The sequence of actions triggered by a user request towards a monitored webapp is:
- A monitored method in the target web application is going to be invoked.
- An aspect associated with that method is invoked. It's connected to the monitoring framework by extending a base monitor aspect class and optionally by calling some of the framework's methods.
- The framework stores data about the monitored method/operation's name, layer and component/resource and its start time. It also checks the thread local stack of responses to find out whether it's invoked as a part of processing some higher level monitored method and if it is the case then it sets it as its parent.
- The monitored method is
invoked and when it finishes, the framework stores its end time. If it
finished with an exception then it's first checked whether the
exception should be indeed regarded as a failure and if yes, the
exception data is stored as well. If the operation was slow or failed, the framework puts it on the list of slowest/recently failed operations and captures its parameters.
- When the original user request is processed completely, the framework aggregates data about its performance. This happens in StatsSummarizer, a ResponseListener. If the request processing was too slow with respect to predefined limits (SLA` usually <1s in 90% of time) then it's stored into the slow operations list and the layer/component that caused the delay is marked.
As said above, performance statistics are aggregated by monitored methods and are collected into a global statistics registry. The registry contains instances of PerfStats or CompositePerfStats, which also implements StatisticsRegistry to hold nested statistics, or a subclass such as OperationPerfStats. A registry is actualy a map of OperationDescriptions to their OperationPerfStats and can return a subset for a particular StatisticsType, for example UI, Database, Remote Call.
Let's see a partial example produced by OperationTracker.registry.dump(new StringBuffer(), 0):
operation(type javax.servlet.Servlet; name org.pentaho.ui.servlet.AdhocWebService):glassbox.track.api.OperationPerfStatsImpl@12c3d18 operation(type javax.servlet.Servlet; name org.pentaho.ui.servlet.AdhocWebService)(# = 0, tm =0,00 ms, #slow = 0, # fail = 0) StatisticsTypeImpl 0 of class glassbox.track.api.UIStatisticsType: StatisticsTypeImpl 1 of class glassbox.track.api.DatabaseStatisticsType: StatisticsTypeImpl 2 of class glassbox.track.api.DatabaseConnectionStatisticsType: StatisticsTypeImpl 3 of class glassbox.track.api.DatabaseStatementStatisticsType: StatisticsTypeImpl 4 of class glassbox.track.api.SimpleStatisticsType: StatisticsTypeImpl 5 of class glassbox.track.api.RemoteCallStatisticsType: StatisticsTypeImpl 6 of class glassbox.track.api.TreeStatisticsTypeImpl: time:Stats (tm=0,00 ms, slow=0) StatisticsTypeImpl 0 of class glassbox.track.api.UIStatisticsType: StatisticsTypeImpl 1 of class glassbox.track.api.DatabaseStatisticsType: StatisticsTypeImpl 2 of class glassbox.track.api.DatabaseConnectionStatisticsType: StatisticsTypeImpl 3 of class glassbox.track.api.DatabaseStatementStatisticsType: StatisticsTypeImpl 4 of class glassbox.track.api.SimpleStatisticsType: StatisticsTypeImpl 5 of class glassbox.track.api.RemoteCallStatisticsType: StatisticsTypeImpl 6 of class glassbox.track.api.TreeStatisticsTypeImpl:
An OperationPerfStats holds e.g. resourceTotalStats and otherComponentStats.
*Stats also hold all other necessary information, for instance about slow/failing cases.
OperationTracker also uses an instance of OperationAnalyzer, which is responsible for preparing data for all the nice output you can see in the UI. This includes summarizing the stats into OperationSummaries and detecting (based on the collected stats) what is the cause of a slow/failing operation and providing this info in the form of OperationAnalysis.
The web UI, aside of handling installation of Glassbox monitoring into a server, maintains connections to all the agents (or to the single local agent in a non-clustered environment) and retrieves all the needed summaries and analysis from them via its OperationHelper.
Currently the web UI only provides statistics about a top-level operation and its list of detected problems (slow SQL, excessive CPU in method XY, ...) with troubleshooting details but you cannot use it to view statistics for its nested monitored methods/components. However you can access those detailed statistics e.g. via the JMX interface.
- You can view results and manage Glassbox using JMX: jconsole
service:jmx:rmi:///jndi/rmi://localhost:7232/GlassboxTroubleshooter . Check $jboss/lib/glassbox/glassbox.properties and glassbox.war/WEB-INF/lib/agent.jar/beans.xml for settings.
- You can disable/enable some monitors at runtime via JMX, for example RemoteCallMonitor or JdbcMonitor. I'm not sure whether there is a way to dis/enable on a more granular level.
Glassbox API - Main classes
Here we will learn about the most important Glassbox classes, what they can do for you, and how they relate to each other.
Classes without an extension are regular java classes while those with .aj are AspectJ classes and need to be compiled by the aspectj compiler.
This API is used by the monitoring aspects to produce the monitoring data that is than further analyzed and presented to the user by Glassbox.
- Collects data about the system's response while processing a request. These are typically nested, i.e., we track times, parameters, etc. for Servlet requests that result in Struts action requests that result in a database query. A response belongs to a particular layer and may have a parent response (when nested). It has also a duration and a status (processing/suceeded/failed/...). Actually it can hold any context, so a monitor can store whatever relevant data is
needed (e.g., this can be useful for a custom metric that your
application wants to track).
- get/setLayer, get/setParent(Response), duration, status (ok/failed/processing..),
- This is a helper class for manipulation requests including their creation while taking care about their proper nesting and setting their start/end times. It uses a thread local stack to keep track of nested requests and System.currentTimeMillis() for timing.
- As noticed elsewhere, its used by monitors to create/finish Responses and produces the appropriate events for that and also manages a list of ResponseListeners.
The monitoring aspects extend this API and it also includes many specific monitoring aspects such as EjbCallMonitor.aj and StrutsRequestMonitor.aj.
- glassbox.monitor.OperationFactory - create OperationDescription(Impl) from JSP path or from a class name - see e.g. MvcFrameworkMonitor.aj
- isEnabled (calls RuntimeControl.aspectOf(this).isEnabled()), setEnabled, setThisThreadEnabled, ...; failureDetectionStrategy (recordException: failureDetectionStrategy.getFailureDescription(throwable)); getLayer();
- accesses & modifies responseFactory.getLastResponse() - e.g. in endNormally (-> response.complete()), endException(); begin(key, layer) -> createResponse
- Ron's note: One reason for having AbstractMonitorClass is to allow using Java-5 annotation-based aspects with the Glassbox framework, either for AspectJ extensions written in that style or for Spring annotation-based aspects.
An addition to the Response API to keep track of requests (monitored methods) etc.
- glassbox.track.api.Request - represent a specific instance of a request to something, i.e. an invocation of a monitored method. They can be compared based on elapsed time.
- glassbox.track.api.FailureDetectionStrategy - shall an exception thrown by a monitored method be regarded as its failure or not?
- glassbox.track.api. Call/Failure/Operation/SQLFailure Description - OperationDescription has a type (e.g. "HttpServlet"), a name (e.g. the servlet's name), context (e.g. the web app's context root) and perhaps a parent OperationDescription if nested.
- glassbox.track.api.SlowRequestDescriptor - describes a request whose processing was too slow; it has among others the attributes StackTraceElement slowestTraceElement and mean/slow/total counts.
- glassbox.track.api.UsageTrackingInfo - attributes eventTime, eventCpuTime, eventUserCpuTime (uses ThreadMXBean)
Used by the framework and UI to analyse the monitoring data and present an aggregated view to the user. These are mostly only value objects while the logic is in the Agent API.
- glassbox.analysis.api.TimeDecomposition - Captures mutually exclusive breakdown of overall time by component/resource. Components: dispatch (in common code above operation), other (other, undefined areas), db access, remote calls; resources: running java code, running native code, waiting (I/O...), thread contention.
- glassbox.analysis.api.OperationAnalysis - TimeDecomposition getComponentDecomposition() (db, cpu, i/o, dispatch...), TimeDecomposition getResourceDecomposition() (by thread use: runnable, blocked, waiting, etc.); getSlowThresholdMillis(); getMeanCpuTime() ...; isFailing(), isSlow();
- glassbox.analysis.api.SummaryStats - aggregated statistics for a monitored method - its accumulatedTime, count (number of hits), mean time
Collect data from monitors, summarize it, analyze problems, and provide the outputs to the Web UI.
- glassbox.client.persistence.jdbc.BackupDaemon - stores agent connections (but not any monitored data) into a database (by default an embedded hsqldb - see the myDataSource below).
- glassbox.monitor.thread.ThreadMonitor15Impl: This monitor periodically grabs thread dumps for all threads that are processing user requests. It runs in a daemon thread collecting the dumps in preset intervals. Creates instances of glassbox.monitor.thread. OperationSample when sampling a monitored thread. When a monitored thread finishes, it results perhaps in a call to ThreadSummarizer.summarize, which updates the assoc. CompositePerfStats.
- glassbox.monitor.thread.ThreadMonitorIntegration.aj: starts a ThreadMonitor after StatsSummarizer.startTopLevelStats|startNestedLaterOperation
- glassbox.summary.StatsSummarizer.aj (implements ResponseListener): ResponseFactory invokes its startedResponse/finishedResponse when appropriate; startedResponse => update ThreadStats including StatisticsRegistry, invoke startedStats which may results in starting a ThreadMonitor
- uses glassbox.track.api.StatisticsRegistry stored in a thread local variable of the type ThreadStats together with first/last operation key (OperationPerfStats)
- glassbox.track.OperationTracker (singleton): used by GlassboxServiceImpl to analyze/list/... operations. Holds a global StatisticsRegistry registry and an OperationAnalyzer.
- glassbox.analysis.OperationAnalyzer: Analyses the collected statisticts to detect problems and their causes. It uses (Default)TimeDecomposition.It also makes OperationSummaries from the stats further used by the UI.
- Note: in agent.jar the Spring config file beans.xml defines a bean operationTracker of the type glassbox.track.OperationTrackerImpl (implements OperationTracker, StatisticsRegistry) - this is used to collect all the stats in the monitored app. It's used by the bean glassboxService (glassbox.agent.control.GlassboxServiceImp).
- glassbox.agent.control.GlassboxServiceImpl (singleton): its listOperations() (delegation to OperationTrackerImpl.listOperations()) is invoked using a local/remote call from the glassbox UI webapp (OperationHelper) to collect operations (stats) from the given server and it also provides problem analysis to the UI in a similar manner.. I suppose that there is only a single instance of this class in a JVM.
UI Web App's API
The Spring configuration file glassbox.war/WEB-INF/applicationContext.xml defines among others the following beans:
- a backupDaemon - regarding its function see glassbox.client.persistence.jdbc.BackupDaemon above. See also glassbox.client.persistence.jdbc.PersistChanges. It's schedule is def. ibidem by scheduledTask with the default period of 10000 and it uses indirectly myDataSource defined there as well.
- Note: To override the data source used to store client configuration including remote connections to open, you can define the System property glassbox.config.ds (this is configured in the applicationContext.xml).
- agentManager (glassbox.client.remote.DistributedAgentManager).
- glassboxService (org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean).
- glassbox.client.helper.OperationHelper - updates statistics to display by calling listOperations on the remote agents.
- glassbox.client.pojo.OperationData - monit. data collected and used by the UI It only adds source and agent identification to its nested OperationSummary, holding the actual statistic (operation count, is failing, is slow, avg time; nested OperationDescription that might have a parent too).
Customizing Glassbox for your webapp
There're two ways of customizing Glassbox for monitoring of a particular webapp:
- Adding monitors
- Glassbox plugins mechanism for advanced customization.
1. Adding monitors
You can apply an existing monitoring aspect to a new method using AspectJ weaving rules described in an aop.xml file thus turning the method into a monitored method or you can even create a new monitoring aspect extending a base Glassbox aspect, putting it - perhaps together with an aop.xml - on the monited webapp's classpath.
Very valuable and inspiring information about this are in the aforementioned presentation Glassbox Architecture & Design.
Coding-less addition of a monitor
Quoting the User Guide:
- Simple installation (1.Deploy webapp; 2. Run postinstall script to copy jars etc.; 3. Restart AS with a command-line option to load glassbox aspects).
Injecting better logging into a binary .class using Javassist
Have you ever been strucked by a completely useless exception message somewhere from the depth of a 3rd party application or library you had to use in your code? Have you ever wanted the bloody nameless programmer to have written a truly informative and helpful error message so that you wouldn't need to spend hours trying to figure out what was the problem that would have been easily discovered if only more context information available at the moment when the exception occured was included in its error message? Have you wondered how only you could inject the necessary logging into the spot? Read on to get the answer.
Add method tracing (params, result) to existing application w/o modifying it
Have you ever needed to learn what's going on in a 3rd-party java application and yet didn't want to debug it and step through it? Were you wishing to be able to see what methods get called in what order together with their actual parameters and return values? There is a "simple" solution: AspectWerkz.
- Download AspectWerkz (I had 2.0)
- Create an aop.xml where you define what methods to observe
- (Optional) Modify the tracer class
- Run the target application with the aspect under Java 5 (AspectWerkz supports also older JVM but that's more tricky):
-cp <some jars from lib/, see below>:./bin:<your classpath>
dom4j-1.4.jar, qdox-1.4.jar, concurrent-1.3.1.jar, trove-1.0.jar (see aspectwerkz-2.0.jar's Manifest)
See: aspectwerkz-2.0\src\samples\examples\logging\* , aspectwerkz-2.0\src\samples\examples\proxy\tracing\*
<!-- the aspectwerkz.definition.file --> <aspectwerkz> <system id="aopRunttimeLoggerExample"> <package name="net.jakubholy.jeeutils.injectedlogger"> <aspect class="TracingAspect "> <!-- Expression: any methods in the package including constructors and excluding the aspect class --> <pointcut name="myPointcut" expression="( execution(* org.hibernate...*(..)) OR execution(org.hibernate.tool.hbm2x...new(..)) ) AND !within(net.jakubholy.jeeutils.injectedlogger.TracingAspect) AND !within(org.hibernate.tool.hbm2x.TemplateHelper) AND !within(org.hibernate.tool.hbm2x.AbstractExporter)"/> <advice name="beforeMethod" type="before" bind-to="myPointcut"/> <advice name="afterMethod" type="after" bind-to="myPointcut"/> </aspect> </package> </system> </aspectwerkz>
And now the tracing class itself:
The Ultimate Web UI Framework
Recently I have found myself in the need of a framework for creating rich, responsive and highly interactive web-based user interfaces that would ideally be easy to use and fast to learn. I was basically only interested in the view part of the presentation tier, that's the UI running in user's browser and interacting with him/her. I had no preferences regarding the 'M' and 'C' of MVC, in other words the server-side of the presentation-tier.
After doing some research I've found a couple of candidates:
- Google Web Toolkit (GWT) with the GWT-Ext components library
- JBoss RichFaces (it is based JSF; perhaps use with Seam)
- Others: Wicket, Grails, Struts 2, ...
You might have already heard about Facelets (docs), a library for Java Server Faces (JSF), and wondered why it is popular and what it is good for. I've wondered too and now I want to share the answers with you.Warning: I'm a novice to Facelets and some things may be not completely exact.
Truncating UTF String to the given number of bytes while preserving its validity [for DB insert]
Often you need to insert a String from Java into a database column with a fixed length specified in bytes. Using string.substring(0, DB_FIELD_LENGTH); isn't enough because it only cuts down the number of characters but in UTF-8 a single character may be represented by 1-4 bytes. But you cannot just turn the string into an array of bytes and use its first DB_FIELD_LENGTH elements because you could end up with an invalid UTF-8 character at the end (one that is represented by 2+ bytes
VMWare: Shrink image even though it’s a snapshot
I needed to shrink a vmware image to save space but it wasn't possible because it wasn't an independent disk but a snapshot (rhel3_ws_u4-000001.vmdk etc.) dependant upon the original disk (rhel3_ws_u4-s001.vmdk etc). The steps were:
Dependency Finder 1.2.0 for Java
Dependency Finder for java can help you to find your way in unknown class files/library.
- Import the class files - File > Extract; wait... Note: you may need to increase the JVM's memory.
- Store the extracted information about the imported classes - File > Save
- Select the programming elements to examine by selecting the proper checkboxes - by default it's set to packages, you may rather want classes or packages+classes.
- Display a dependency 'graph' - File > Dependency. The symbol --> means uses, <-- means is used by.
- You may want to limit the elements for which to show dependencies (the box Select programming elements) or their dependencies to show (the box Show dependencies (stop for closure)). The expressions use Perl regular expressions (RegExp): you specify 1 or more RegExp enclosed by '/' and '/' and separated by a comma. Example: classes containiny MyClass and (presumabely) packages starting with com.ibm: /MyClass/,/^com.ibm/
- Previous (23)Next (1)