TBD
Ulyp is a Java recording debugger. Usage is relatively simple.
-
First, download or build the agent
-
Second, use system properties in order to enable the recording. Here is the minimum set of options one will need for recording.
-javaagent:~/Work/ulyp/ulyp-agent/build/libs/ulyp-agent-0.2.1.0.jar -Dulyp.methods=**.HibernateShowcase.save -Dulyp.file=/tmp/hibernate-recording.dat
All methods with name save
and class name HibernateShowcase
(regardless of the package) will be recorded including all nested method calls.
-
Run your code with system properties set.
@Transactional public void save() throws Exception { User user = new User("Test", "User"); saver.save(user); }
-
Run the UI and open the recording file. Enjoy the view
Build with gradle:
./gradlew build
Build without tests:
./gradlew build -x test
Run UI:
./gradlew :ulyp-ui:run
All instrumentation is done using byte buddy library.
All Java objects are recorded by the recorders.
Each recorder supports a particular set of Java types and is responsible for serializing object
values into bytes. SBE library is used for serializing objects into bytes.
Note that Ulyp doesn't fully serialize objects. Let's say, for String
the first couple of hundred symbols are only recorded.
All data is written to file in a flat format. UI later uses RocksDB in order to build the index
The agent has functional tests. The agent is built and then used to record Java subprocess execution. The recording is then later analyzed and verified. Here is the example of test.
Currently, none of java standard library classes are instrumented. This means calls of, let's say, add
method of java
collections are not recorded. However, Ulyp does record object values of java system library classes like strings, numbers,
collections (more on that below) etc.
Type initializers (static
blocks) are not recorded and there are no plans to support this.
Constructors are not recorded by default (which may distort the view), but may be recorded by specifying system prop -Dulyp.constructors
. The reason why constructors
are not recorded by default, is simply that it's not possible to instrument constructors in such fashion that any exception thrown inside the constructor
is caught and rethrown. But this is exactly what should be done, but is not possible. Therefore, when such case happens, the corresponding recording file
may become invalid. In that case UI will show error, and a user should disable the option and run the code again without constructors recorded.
Collections are not recorded by default but can be with system prop -Dulyp.collections
. The available values are JAVA
and ALL
. When set to ALL
all collection values will be recorded (actually only first three items are recorded). This means Ulyp
will iterate any object which implements java.util.Collection
interface. This may be too much especially for certain programs
where there are a lot of proxy collections (like Hibernate or Hazelcast proxy collections when iteration triggers network calls).
Hence the JAVA
option value which only records Java collections.
Try running some code with additional properties -Dulyp.constructors -Dulyp.collections=JAVA
to see the difference:
Hotkey | Action |
---|---|
Hold Shift | Show full type names |
Press = | Increase font size |
Press - | Decrease font size |