This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 258423 - Improve the new profiler architecture to reflect the Java ME Profiler requirements
Summary: Improve the new profiler architecture to reflect the Java ME Profiler require...
Status: RESOLVED FIXED
Alias: None
Product: profiler
Classification: Unclassified
Component: Base (show other bugs)
Version: 8.1
Hardware: PC All
: P1 normal (vote)
Assignee: Jiri Sedlacek
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-03-17 18:59 UTC by alexander.burdukov
Modified: 2016-06-29 23:39 UTC (History)
0 users

See Also:
Issue Type: ENHANCEMENT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description alexander.burdukov 2016-03-17 18:59:18 UTC
In NetBeans 8.1 Profiler API was heavily re-designed and became too Java SE specific. As the result Profiler support for Oracle Java ME SDK is broken. We found a partial "dirty" workaround, but it is not really good.

What is wrong:
Now starting of Profiler always opens ProfilerWindow that belongs to selected project with features that belong to Java SE only and which cannot be disabled or hidden. E.g., for Java ME
 - there is no Methods/Threads/Objects/Telemetry/Locks features, there is only one sampling static (not live) CPU profiler feature that belongs to a project
 - Profiling Points has no sense (both in the ProfilerWindow and in the main Profile menu)
 - Multiple modes are not applicable
 - Two special Java ME profiler features (Network Monitor and Memory Monitor) belongs to a devices where the project is run, but not to a project itself (so ProfilerWindow has no sense for them).

So, what is required to resolve this issue:
1. Provide an ability to start profiler without showing ProfilerWindow (both from main Profile menu and project popup menu). I.e., see ProjectSensitivePerformer.perform method:

    @Override
    public void perform(final Project project) {
        RequestProcessor.getDefault().post(new Runnable() {
            public void run() {
                ProfilerSession session = null;
        
                Lookup projectLookup = project.getLookup();
                if (attach) {
                    Lookup context = new ProxyLookup(projectLookup, Lookups.fixed(project));
                    session = ProfilerSession.forContext(context);
                } else {
                    ActionProvider ap = projectLookup.lookup(ActionProvider.class);
                    if (ap != null) {
                        ProfilerLauncher.Command _command = new ProfilerLauncher.Command(command);
                        Lookup context = new ProxyLookup(projectLookup, Lookups.fixed(project, _command));
                        session = ProfilerSession.forContext(context);
                    }
                }

                if (session != null) {
                    session.setAttach(attach);
                    session.open();
                }
            }
        });
    }

    Instead of this code that opens sessions and eventually ProfilerWindow we need just invoking action provider, e.g. in the following way:

    @Override
    public void perform(final Project project) {
        RequestProcessor.getDefault().post(new Runnable() {
            public void run() {
                final Lookup projectLookup = project.getLookup();
                final ActionProvider ap = projectLookup.lookup(ActionProvider.class);

                if (ap != null) {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            ap.invokeAction(command, new ProxyLookup(projectLookup,
                                    Lookups.fixed(project, new ProfilerLauncher.Command(command))));
                        }
                    });
                }
            }
        });
    }

    What kind of code should be invoked can be determined using some new option from ProjectProfilingSupportProvider

2. Provide an ability to exclude a project from "New Profiling Point" dialog (man menu Profile>Insert Profiling Point...), e.g. basing on some new option from ProjectProfilingSupportProvider
Comment 1 Jiri Sedlacek 2016-03-23 14:03:32 UTC
You're right that the implementation of ProjectSensitivePerformer.perform() is too Java SE specific - in fact the containing module provides a concrete Java SE and Java EE profiler implementation. It shouldn't be modified to enable Java ME Profiler integration with different UI and workflow.

Ideally a new module with Java ME profiler implementation should be created. It will provide the correct UI and workflow for your needs. The Java SE profiler implementation should be disabled in this case as well as other modules which are not needed (Profiling Points). This is currently not possible.

The Insert Profiling Point... menu item can be hidden by editing the layer.xml file of one of your modules. In case it needs to be project-specific a new API for this menu item needs to be introduced.
Comment 2 alexander.burdukov 2016-03-23 14:46:40 UTC
Please, note that in case of Java ME most probably it is impossible to create generic Java ME profiler implementation since Java ME profiler is specific to particular Java ME platform implementation (Java ME SDK in our case).

On other hand currently we are able to re-use the most of required functionality from Java SE profiler.

Basically following features are required for us:
1. Enable/disable profiler per project. At the moment it is covered by ProjectProfilingSupportProvider.isProfilingSupported.

2. Check if the project is modified for profiler, modify project for profiler (if not modified yet and if permitted by the project) and launch it if modified. Currently it is covered by ProjectProfilingSupportProvider.checkProjectIsModifiedForProfiler which we invoke from our action provider. This is only solution with the current profiler API, but probably it is better to separate these 3 actions (check, integrate, launch) from API point of view. Note, that launch action in this case must run custom action contributed by our plugin.

3. Unintegrate profiler if permitted by the project. It is covered by ProjectProfilingSupportProvider.supportsUnintegrate and ProjectProfilingSupportProvider.unintegrateProfiler. However, I do not see this feature in NetBeans UI anymore, so probably these methods just have to be removed from API.

Also, we reuse NetBeans Profiler UI to display CPU profiler results by extending classes like CPUCCTContainer, CPUResultsSnapshot, PrestimeCPUCCTNodeBacked
Comment 3 Jiri Sedlacek 2016-06-15 15:23:50 UTC
Addressed by http://hg.netbeans.org/profiler-main/rev/80011f6df639:

Before starting the profiling session the ProjectProfilingSupport.checkProjectCanBeProfiled() method is called. This is the right place to integrate the ME profiler with the project if needed.

When starting the profiling session, you can take control of what will happen by implementing ProjectProfilingSupport.startProfilingSession() and returning true from this method.

Returning false from your ProjectProfilingSupport.areProfilingPointsSupported() will remove the ME projects from the Profiling Point wizard.

There's no support for unintegrating the profiler from projects as this is no more needed by the Java profiler. You can create your own action in the Profile menu and provide your implementation for this functionality if needed.
Comment 4 alexander.burdukov 2016-06-29 23:39:37 UTC
Verified the new API with manual built NetBeans. Works for me and no more modifications are needed.