Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Bundle #184

Merged
merged 164 commits into from
Mar 3, 2017
Merged

Conversation

PhRX
Copy link
Contributor

@PhRX PhRX commented Feb 7, 2017

This PR supersedes #173, which pretty much is obsoloete given the volume of changes.

It almost concludes the work I wanted to do. An overview of the changes can be found below.

Since the amount of code is probably larger again than what's in #173, reviewing isn't getting any easier. I'm aware of this. but IMHO having to wait for reviews should not hold up progressing on the project if the progress is on a large enough scale.

I'd like to propose the following procedure :

  • Create a new branch in the original HP repository called "approval"
  • Close the 2 PRs (this one and Many new functions for the Profiler JavaFX UI #173)
  • Let me create a new PR pointing at the "approval" branch
  • Merge the PR into "approval"
  • In the instructions, make people aware there's an alternative approval branch which has more features
  • Let people use it for a while; if possible, also review the code
  • If possible, have somewhere where people can vote for/against the "approval" changes
  • If enough people agree that it works and is a worthwhile evolution, and any bugs or issues found by users have been fixed, integrate the branch into master

This way, we add an alternative standard for PR acceptance next to code review : enough users being happy as yardstick. Also, a branch on master is more visible than "just another fork".

Please let me know whether that works for y'all.

So, in addition to what's in #173, the following features have been added :

  • Fix for Have the option to Collapse different trees into one tree across different threads. #36 : the aggregation options (see below) allow collapsing thread trees into an aggregated tree
  • Fix for disambiguate "duplicate" methods #38 : the aggregation options allow inclusion of the line nr, which disambiguates the method calls (but having the signature somehow would be even nicer)
  • Fix for Make the tree view a snapshot #78 : during "live" profiling, the profile can be "frozen", so the front-end no longer receives updates. When unfreezing, the view will be updated to the current situation.
  • Fix for Can't open Log Files > 2GB #175 : large log files can now be opened. The log files are no longer memory-mapped in their entirety, instead the buffer now is a "moving window".
  • Fix for LogCollector Incorrectly Aggregates Top-level Frames #179 : top-level frames (children of thread-level) are now aggregated correctly
  • The Self Time and Total Time, available in the agent output, is now exposed in all views
  • Aggregation can now be switched as follows :
    • Frames : By Fully Qualified Method Name, By FQMN + Line Nr, By FQMN + BCI
    • Threads : All threads together, Threads by Id (tree views only), Threads by name (tree views only)
  • The source profile (LeanProfile) now contains the minimum of information without redundancy, to ensure the collection thread has to do as little work as possible
  • Pull mechanism for profiles : the front-end now requests updates, which allows it to control the update rate (but no UI controls have yet been provided except for the "freeze" buttons)
  • Aggregation happens lazily and is cached
  • Tree Diff view for comparing two profiles
  • Added Infobar with help information
  • In the Flat view (list of methods), when selecting a method, its ancestors (methods directly or indirectly calling the selected method) and descendants (methods directly and indirectly called by the selected method) are shown in two trees at the bottom of the screen
  • In the Tree view, when selecting a method, its descendants are aggregated into a list shown at the bottom
  • Added more columns in all views, with homogenous labeling
  • Added QuickFilter function for filtering the key
  • Prevent opening the same source twice
  • Fixed VirtualMachine source issue where the log file produced by an agent couldn't always be located
  • Included font with non-proportional digit characters for more readable number tables
  • Smaller default font size (through CSS)
  • On refresh, expand TreeViews by 1 level
  • Sorting is preserved (at least in flat views) when the aggregation is updated
  • I18N for all text (except some enum choices, still got to figure out the pattern for that)
  • Remember parent directory when opening a log file, to prevent lots of renavigating to the same or similar location

At code level, the following was changed :

  • New core.aggregation package added, containing :
    • aggregator package with the actual aggregation transformation logic
    • filter package with more generalized filtering logic
    • grouping package with "key grouping" logic for aggregation
    • result package with the aggregation data structures
  • New core.collector.lean package containing the new LeanLogCollector which implements the pull mechanism and which produces the more lightweight "LeanProfile"s
  • New core.profiles.lean package containing the data structures for the new "lean" profiles
  • Extracted common functionality from controllers and put it into abstract superclasses for code reuse
  • Use JavaFX tasks to decouple profile generation and initial aggregation from front-end
  • Documented many methods and classes (but some documentation eneds to be revisited due to recent fixes and refactorings)

Still to do, optionally :

  • Percentages are now calculated relative to the "global aggregation", over threads. Allow reference switching to thread-level where appropriate (i.e. in tree views aggregated per thread, show percentages relative to thread total rather than relative to sum over all threads)
  • In addition, maybe add option not to take the "error" counts into account when aggregating ?
  • Highlight filter hits (useful in tree filtering)
  • Maybe add aggregated ancestors/descendants views to flat diff and tree diff ?
  • Make tabs/profiles closeable
  • Add Preferences, including styling options (font size, ...)
  • Clearer QuickFilter UI ? (show currently active quickfilter, to avoid confusion when something was typed in the text field but not "activated")
  • Add Clear QuickFilter button / Clear All Filters button
  • Remember selection when aggregation is updated
  • Remember which tree nodes were expanded/collapsed when aggregation is updated

arickp and others added 30 commits December 26, 2016 11:12
  * Eclipse plugin : execute "gradle eclipse" to generate an eclipse
project
  * Application plugin : execute "gradle run" to start the JavaFX UI
one contains the name. Instead of creating new ThreadMeta objects in the
profile, update the existing one if it has "more accurate info (i.e. a
non-empty threadName).
[Corrected with spaces instead of tabs]
Multiple ThreadMetas are emittled for the same thread but only the first
one seems to contain the ThreadName. So instead of putting the last seen
ThreadMeta in the profile, the ThreadMetas are merged.
This reverts commit 7b48244.
Seems that local git settings were not auto-converting the line endings
yet.
[Corrected with spaces instead of tabs]
[Corrected CRLF settings]
[Formatting as close to original as I could get it with Eclipse
formatter settings]

Multiple ThreadMetas are emittled for the same thread but only the first
one seems to contain the ThreadName. So instead of putting the last seen
ThreadMeta in the profile, the ThreadMetas are merged.
Using the same formatter settings for the project allows contributors to
keep formatting consistent. This one was exported, after configuration,
from Eclipse Neon 4.6.2.

It is as close to the original formatting as I could get it. Any
improvements welcome.
The Flat Profile Entries now contain percentages, which are already an
aggregation. This makes later aggregation (e.g. in the UI) much more
difficult. The self/total sample counts are the "raw data", and can
later be aggregated in different ways (e.g. show how much time is spent
in a particular package).

The traceCount has been added because there's no link (yet) to the total
sample count. This may need to be reworked, with the total sample count
being kept at Profile level, and aggregation to percentages taking place
there.
…m-profiling-tools#78)

The Profile.copy() method allows creation of a deep copy. This decouples
the profile publication from processing on the output (ui, console, ...)
side.

This means for instance that filters in the UI can be applied on a copy,
and when the filter is removed, the original profile can be reinstated.

The copy also can fulfill the role of a snapshot (i.e. for implementing
jvm-profiling-tools#78).
Calculate the septh of the descendant tree of a ProfileNode.
New StringFilter superclass with implementations for filtering on
classname and on method name.
There's also support for more filtering modes : contains, startsWith,
endsWith, ...
This is the first step of a big refactor + functionality leap.
The step is split out in order to ensure git properly keeps track of the
change history.
Renaming the Controllers to [something]Controller. Separate step to
allow git to track rename easily.
More moving to different packages, allowing git to track easily.
Move FXML files to a subfolder called "fxml", making room for other
subfolders for css and icons.
Add new resources : icons and css
Add Utility classes used in upcoming functionality.
TimeShareFilter extended with more comparison features.
Bring FXML filenames in line with Controller name pattern
List of functional changes :

- Allow opening multiple profiles
- Instead of Landing View, open log files or machines from Menu Bar
- Use Choice Box for selecting views
- Specify filters using UI instead of a string description
- Extended filter capabilities :
  * Also filter on Method Name
  * Added several comparison operators
  * Allow hiding threads which contain only "error" frames
    (works only in Tree View)
- Changing filter or removing filter will reapply filters to
  "original" profile which was filtered
- Collapse All / Expand All buttons added in Tree View
- Right-click on node in tree view for more expand/collapse options
  on the node itself
- Allow creating a diff of the flat views between two profiles
  (keyed by method name)
  * Diff view shows base and new numbers, and highlighted difference
- Export flat view or diff view as currently shown (i.e. filters
  taken into account) to a CSV file (using export button)
- Export (part of) a stack in tree view to a text file by
  right-clicking the node
- Show Thread Names in Tree View when known
- Show sample counts as well as percentages
The result is a more compact and more easily interpretable view.
Also, an icon is added to show whether the profile comes from an HPL
file or is "live"
The VM names in the Monitor menu and elsewhere can be way too long
because of extra java options in the process name. Shortened to first
occurrence of space character.
Since my personal use case is mostly offline processing of hpl log
files, the "live monitoring"option hadn't been tested yet. Since on
testing the heuristics apparently can't locate the hpl file for a live
vm on my machine, and since the "live" mechanism actually also reads
from a "live" log file, the new menu item allows you to open a "live"
log file, and that works nicely.
For now I left the "monitor" menu, in the hope of finding a way to
locate the log file produced by the agent somehow.
Copy link
Contributor

@chhsiao90 chhsiao90 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just think it would be better if more people help review on this awesome PR!

Please see a few comments in the code.

The PR had two major modification, one is LeanProfile, and other is gui improvement.
The gui part I think it was great, I was enjoyed at the fancy user interface!
But if there is a start page, that would be better!

For LeanProfile part, I think it still need some times to find potential bugs or typos.
But the code was awesome!

BTW, Gradle stuff appeared in this PR, I think it was still better to be removed for #173 (comment)

this.className = className;
this.methodName = methodName;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a suggestion.
Is that modify the original constructor to private and create another public method Method construction will be more readible?

    public static Method of(long methodId, String fileName, String className, String methodName)
    {
        return new Method(methodId, fileName, formatClassName(className), methodName);
    }

    private Method(long methodId, String fileName, String className, String methodName)
    {
        this.methodId = methodId;
        this.fileName = fileName;
        this.className = className;
        this.methodName = methodName;
    }

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of scope, lets not add further changes to this already massive PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for helping with review this PR @nitsanw and @chhsiao90 - greatly appreciated! I still think we should keep to one build system and not have it as part of this PR. I don't mind if we move to gradle in future, but let's not bundle that up in these changes.

}

return this;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it still can keep this class' immutability as following.
immutable still better than mutable!

    public ThreadMeta update(ThreadMeta newMeta)
    {
        if (newMeta.threadName != null && !newMeta.threadName.isEmpty())
        {
            return newMeta;
        }

        return this;
    }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in upcoming commit, along with ThreadInfo which follows the same pattern.

public LeanNode copy(LeanNode newParent)
{
return new LeanNode(this, newParent);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not very straightforward for the method name copy.
Because it didn't just copy, but also set a new parent for it...
It will be better if it had a more proper name, but still acceptable for me :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in upcoming commit, by getting rid of the two copy() methods. One was unused, and the one referenced here was used only in a single location where it didn't hurt readability to replace it by a constructor call.

* Copy constructor.
*
* @param source the source LeanNode which is being copied
* @param new Parent the parent of the copy (which itself generally is a copy)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new Parent => newParent

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in upcoming commit.

// Aggregation Methods

/**
* Aggregates teh information from a child {@link StackFrame} into the children of this LeanNode, updating the total
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

teh => the

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in upcoming commit.

/**
* Sets the {@link ApplicationContext} and propagates it to any contained controllers.
*
* @param appCtx the {@link ApplicationContext}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appCtx => applicationContext

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in upcoming commit.

int logPathEnd = commaPos > 0 ? commaPos : (spacePos > 0 ? spacePos : agentPath.length());

return new FileLogSource(new File(agentPath.substring(logPathStart, logPathEnd)));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this part had three problem that cause my hp-gui cannot attach to a running jvm correctly.

  • The jvm only had -agentpath as vmArgs that will cause ArrayIndexOutOfBoundsException
java -agentpath:/Users/han-pc/IdeaProjects/honest-profiler/build/liblagent.dylib=interval=100 -cp classes  InfiniteExample
  • The jvm didn't defined custom logPath
java -agentpath:/Users/han-pc/IdeaProjects/honest-profiler/build/liblagent.dylib=interval=100 -cp classes -Dwhatever=Y InfiniteExample
  • The jvm define logPath with relativePath, but was running on different folder with hp-gui
java -agentpath:/Users/han-pc/IdeaProjects/honest-profiler/build/liblagent.dylib=interval=100,logPath=tmp.hpl -cp classes -Dwhatever=Y InfiniteExample

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these problems not present with previous version?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No,
previous version seems only used getLogSource() to get latest log file at userDir
And current version used getLogSourceFromVmArgs() depends on vmArgs

Copy link
Contributor Author

@PhRX PhRX Feb 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, my bad, I'll check and fix. The intention was to revert to the original logic if no logpath parameter was found, so as to only extend the number of cases in which the mechanism works correctly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in upcoming commit. I hardened the code, by introducing early checks if what we're looking for is present at all, and revert to original getLogSource() if it isn't. Also, the final File is checked for existence, and if it doesn't, revert to the original getLogSource() as well.

private BigInteger totalTime;

private int selfCnt;
private int totalCnt;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that selfCnt or totalCnt had the risk for overflow?
int -> BigInteger will be better?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that this is a number of samples, and that INT_MAX is rather large, it would take a program which samples 1000 times a second nearly 50 days of profiling to overflow. I would not worry.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @nitsanw for doing the calculations for me :) This is pretty much what I intuited, when deciding between long and int (BigInteger would have been overkill), but I never actually did the math. The only reason for the BigInt is that when working with nanos, you potentially do get really big numbers.

- Several javadoc typos fixed
- Made ThreadMeta and ThreadInfo immutable
- Removed copy() methods from LeanNode
- Cleaned up and hardened VirtualMachine LogSource generation, reverting
to original logic if no agentpath or logPath parameters are defined in
the JVM args
@PhRX
Copy link
Contributor Author

PhRX commented Feb 9, 2017

Thanks @chhsiao90 and @nitsanw for the review.

@RichardWarburton I forgot to reply, but I agree (and I already closed the old PR), although I'd like to do something about the visibility of the new stuff - a fork is in my (limited) experience very easily ignored entirely.

I'll finish up the documentation - only some utility classes are undocumented, and I'll probably write some package documentation which should make it clearer how the concepts work together - I can imagine that things like Grouping and Target may be a bit confusing or obscure when first coming across them. Some pictures or at least some text with a top-down explanation might clarify (comments in the code are by nature more bottom-up).

Copy link
Contributor

@chhsiao90 chhsiao90 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few more comments!
Hope my review could bring some benefit for you :)

* {@link TraceStart} following it
* @param child the child {@link FrameInfo} of the current LeanNode
* @param last a boolean indicating if the child is the last in the stack trace sample
* @return this node
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that the method return this node, or return child node !

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in upcoming commit.

v.addSelf(nanos) :
// Child is not last in stack, return existing child (its "total" numbers will be updated when its
// child is added)
v));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part is a little complex...
Can I simplify this logic with following description about this part.

  • create child LeanNode if childMap absent
  • addSelf if last

The code will turn into following code snipped if I'm correct...

    public LeanNode add(long nanos, FrameInfo child, boolean last)
    {
        // Non-self add, which updates total time and sample count only.
        data.add(nanos, false);

        LeanNode childNode = childMap.computeIfAbsent(child, k -> new LeanNode(k, this));
        if (last) {
            childNode.addSelf(nanos);
        }
        return childNode;
    }

What do you think!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, excellent catch ! This is indeed a lot simpler. As a bonus I can get rid of the "self constructor" as well, as well as a now obsolete constructor in NumericInfo.

Thanks !
Fixed in upcoming commit.

{
// Class Properties

private static final long SECONDSTONANOS = 1000 * 1000 * 1000;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SECONDS_TO_NANOS would be better :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in upcoming commit.

PhRX and others added 7 commits February 9, 2017 10:44
- Fixed javadoc typos
- Better constant name
- Simplification of LeanNode aggregation code
I'm not adding comments to the Cell and TreeItem subclasses in the
ports.javafx.view package, they are by and large too trivial.

Also, I'm bored stiff after almost two days of writing javadoc comments.
But it is a useful exercise nonetheless, you end up reviewing all of
your code :)
Otherwise the generated html is all bunched up, since like HTML javadoc
doesn't preserve whitespace.
Contains a description of the profiler basics and the LeanProfile
structure and aggregation.
@PhRX
Copy link
Contributor Author

PhRX commented Feb 9, 2017

To all potential reviewers : in my most recent commit I added the package description for the core.profiles.lean package.

I very very highly recommend reviewing it early on, since I tried to describe in detail the profiler basics, the internal structure of the LeanProfile data structure (which the core data structure on top of which all aggregations are built), and how the numerical data in there is (minimally) aggregated.

As a result, the text pretty accurately reflects many of my presumptions and assumptions when I wrote the code. Therefore, if there are any conceptual mistakes in this text, it is fairly certain that those mistakes are reflected in the code !

Unfortunately for me the converse is not true - if the text is accurate and sound, it doesn't mean the actual code is correct :-/

Of course an additional benefit of reading it is that the LeanProfile structure should be clearer afterwards.

The documentation describes how all the aggregation data structures hang
together, how aggregations can be created and filtered etc.

And the Method Id grouping ? Well I accidentally added a line saying it
was supported in the documentation. While reviewing I figured out it
wasn't. But it was sooooo simple to add it... Couldn't resist it. Sorry.
@RichardWarburton
Copy link
Member

Hi,

I've tried out the new JavaFX UI and in general it looks good. I like the multiple profile tabs and the comparison view - good improvements.

I've noticed a couple of things that look like regressions:

  • If you start another Java program, it will appear in the monitor menu, but if you quit the other program then its entry won't disappear from the menu.
  • If you file->quit or click X in the ui after you have opened a log it closes the window, but doesn't actually exit the Java process.
  • When I try to monitor a program I get the following exception:
java.lang.StringIndexOutOfBoundsException: String index out of range: -11
	at java.lang.String.substring(String.java:1967)
	at com.insightfullogic.honest_profiler.core.sources.VirtualMachine.getLogSourceFromVmArgs(VirtualMachine.java:73)
	at com.insightfullogic.honest_profiler.ports.javafx.model.task.InitializeProfileTask.monitor(InitializeProfileTask.java:80)
	at com.insightfullogic.honest_profiler.ports.javafx.model.task.InitializeProfileTask.call(InitializeProfileTask.java:45)
	at com.insightfullogic.honest_profiler.ports.javafx.model.task.InitializeProfileTask.call(InitializeProfileTask.java:22)
	at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

@PhRX
Copy link
Contributor Author

PhRX commented Feb 10, 2017

Hi @RichardWarburton,

Thanks for the testing ! I addressed the 3 issues you mentioned :

  • The JVM Stop not being detected seems not to have been a regression, but an issue in the "original" code : it would always try to attach a VM also in the "close" case. "attach" is now called only once as well (which addresses the TODO comment in there, which I now realize I forgot to remove). Not sure if there is a case for "remembering" descriptors after a failed attach, and trying to attach again on subsequent polls ?

  • The Java process would exit eventually, but I made it snappy by ensuring the executor service in the application context gets shut down on application close, and that LocalMachineSource doesn't ignore being interrupted but triggers the ThreadedAgent interrupt logic properly.

  • Are you sure that you're running the latest version from the integration thread ? The line numbers in the exception didn't match up with mine, and in 54f7910 I hardened the "logPath extraction" code quite a bit (precisely to avoid the OutOfBounds exceptions like you're seeing). I reviewed the code again, and added a minor fix, but that corner case (the args containing "logPath" but not "logPath=") should not have applied to your test.

@PhRX
Copy link
Contributor Author

PhRX commented Feb 10, 2017

@RichardWarburton @chhsiao90 I was very focused on finishing the documentation yesterday, I didn't have time yet to remove the gradle bits (again). Will do so shortly.

@chhsiao90 and others : Is the landing page important ? Which functions or information would you like to see there ? It's not very difficult to reinstate but its functions have effectively been superseded by the menu options, and at the moment, once a profile has been opened, the landing page would never be seen again (because I haven't yet implemented any profile closing functions). That said, while mulling this yesterday I did realize the initial view looks a bit early 90s :-) (i.e. unwelcoming big blank area of nothing).

Suggestions and feedback more than welcome !

@chhsiao90
Copy link
Contributor

@PhRX - landing page is not very necessary and seems not import with this PR.
I think keep empty in current version is fine :)

While I don't plan on adding any features to the jvm-profiling-tools#184 PR, this is a
simplification which should actually make it easier for reviewers to
understand the code, since Dialogs and Dialog Controllers now are
handled much the same way as the other ViewControllers, using FXML
injection, instead of the roundabout FXMLLoader stuff and explicit
Dialog object configuration.

Up to now, I never found any resource on the web documenting how to
nicely do Dialogs this way. But I finally figured it out, after seeing a
couple of sentences buried in
https://docs.oracle.com/javase/8/javafx/api/javafx/fxml/doc-files/introduction_to_fxml.html
, specifically the remark about needing to nest it in an fx:define.

It doesn't help that SceneBuilder also offers no support for this
mechanism.

Anyway, instead of the ugly explicit FXMLLoader way which you can find
in almost any discussion of Dialog creation on the 'Net, which among
other things requires explicit FXML paths in the source code, here is
now what I strongly suspect is the 'proper' way to do it through FXML
controller injection. Yay. And I missed my train because of this.
@RichardWarburton
Copy link
Member

Hi @PhRX re: "Are you sure that you're running the latest version from the integration thread?" - I cloned a repo from your PR and used the compiled binary from that to produce the log. It was the latest commit as of the comment. I'll re-test this evening with your latest pushes into this PR.

@PhRX
Copy link
Contributor Author

PhRX commented Feb 13, 2017

Hi @RichardWarburton I didn't even know you could clone from a PR. If you want me to, I can update the code to collect more information and make the Exception describe precisely what went wrong. I just re-eyeballed the current state and I don't see anything anymore that could cause trouble - either the agent was attached to the JVM with -agentPath + a logPath arg, in which case the file described by logPath will be returned, otherwise the old code is invoked.

Thanks for testing !

PhRX added 2 commits February 13, 2017 11:09
Back when switching to the new data structures, this fell by the
wayside. Now the "Export" function of nodes of (non-diff) treeviews
works again.

This is my last commit for this PR, apart from potential fixes for bugs
or issues reported by reviewers, or if I discover through my own usage
any really bad bugs.
@RichardWarburton
Copy link
Member

After both using the build of this for a while and talking to @nitsanw I've decided the best thing is to merge this PR and cleanup any remaining issues afterwards. But please, please, please send single-purpose PRs in future!

@RichardWarburton RichardWarburton merged commit 98bdb71 into jvm-profiling-tools:master Mar 3, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants