Rhapsody plugin Java API, extremely slow execution - eclipse-plugin

I have used Rhapsody Java API, to create a plugin for my rhapsody project. My problem is that it is extremely slow. I have the following function:
private static void collectElements(final IRPModelElement curEl,
final IRPCollection elCol) {
// collect contained elements
for (Object it : curEl.getNestedElements().toList()) {
IRPModelElement element = (IRPModelElement) it;
if (!skipElement(element)) {
// add element itself
elCol.addItem(element);
// descend
collectElements(element, elCol);
}
}
}
that collects all the nested elements of the selected element. My project has about 7500 elements and it takes 22 seconds to do the above function. I tried to get all the elements with selectedElement.getNestedElementsRecursive() and to work with List or HashSet, but the .toList() function is also extremely slow. Any suggestion?

For some reason, Rhapsody add-ins run much (much) faster when run within the internal Rhapsody virtual machine.
To do this, compile your java into a .jar and configure your model with a helper file to link a Rhapsody trigger (generally a tools menu or context menu option) to the jar.
Running add-ins this way uses the common Rhapsody virtual machine and is faster, but beware! The java version depends on what the Rhapsody version you're using is set up for and name clashes can be a problem (if you have multiple add-ins with 2 classes of the same name, Rhapsody will load in only one).
More information on setting up helper files can be found on Andy Lapping (an IBM employee)'s website here.

Related

What could be causing an "unresolved external symbol IID_ICallbackWithNoReentrancyToApplicationSTA" error?

Just googling or duckduckgo'ing
unresolved external symbol IID_ICallbackWithNoReentrancyToApplicationSTA
Only brings up a single direct hit and that doesn't even help the person reporting the problem, so I'm hoping some C++/WinRT people run across this question.
While I can't share all the source (tons of interweaved proprietary files) I can share the scenario and a breakdown of what the code changes were; also, there's very little mention of IID_ICallbackWithNoReentrancyToApplicationSTA anywhere. Coincidentally, it appears on GitHub for some Kenny Kerr stuff. The project I'm having problems with is a C++/WinRT project, so that seems like a relevant trapping, especially since there are mentions of xlang which is supposed to be an abstraction of C++/WinRT.
Scenario: A C++/WinRT library is being consumed by a One Core UAP C++/WinRT application/service. The build breaks when trying to use the lib created by the library when building the app/service.
Code Changes: I implemented some PPL tasks into the library, specifically some concurrency::task<void> that do some I/O on a new thread used in the C++/WinRT lib that is being consumed by the app/service. It's an std::thread that uses a lambda that takes copies of objects and performs I/O. Something like this:
std::thread writer([content_vector, json_string, content_file_name, json_file_name]() {
auto write_content = Helper_IO::Overwrite_Lines_Concurrent(content_file_name, content_vector);
auto write_json = Helper_IO::Overwrite_File_Concurrent(json_file_name, json_string);
write_content.get();
write_json.get();
});
Helper_IO::Overwrite_*_Concurrent are both static and both return a concurrency::task<void>
I've tried using writer.detach() and writer.join(), but the results are the same.
Use Project > Properties > Linker > Input > "Additional Dependencies" setting, add uuid.lib.
Some background, identifiers whose names start with "IID" are {guids}. Data, not code. The MSDN documentation is often inadequate to tell you what library you need to link, too focused on documenting functions. My favorite technique is to use a grep-like tool (I use the Far file manager, a bit to obscure to recommend) and search the SDK's lib directory for the string.

OpenTest custom test actors

I'm really impressed with OpenTest project. Found it highly intriguing how many ideas this project is sharing with some projects I created and worked on. Like your epic architecture with actors pulling tasks.. and many others :)
Did you think about including other automation technologies to base Actors on?
I could see two main groups:
1 Established test automation tooling like TestCafe (support for non-selenium gui testing could leverage the whole solution a lot)
2 Custom tooling needed for specific tasks. Would be great to have an actor with some domain-specific capabilities. Now as I can see this could be achieved by introducing another layer of execution worker called by an actor using rest api. What I mean is the possibility of using/including them as new 'actor types' with custom keywords releted.
Thank you for your nice words. We spent a lot of time thinking through the architecture and implementation of OpenTest and it's very rewarding to see that people understand and appreciate the design.
Implementing new keywords (test actions) can be done without creating custom test actors, by creating a new Java class that inherits from the TestAction base class and override its run method. For a simple example, you can take a look at the implementation of the Delay test action. You can then package the new test action in a JAR and drop it (along with any dependencies) in the user-jars subdirectory in your test actor's working directory. The test actor will dynamically load all the JARs it finds in there and will find the new test action class (using reflection) so you can make use of it in your tests. Some useful info and things to look out for:
Your Java project is going to have to define a dependency on the opentest-base project (which is where the TestAction base class is implemented).
When you copy the JAR to where your test actor is, make sure to copy any dependency JARs along with it. Please note that a lot of the dependencies that you might need are already included with the core test actor binaries (you can have a look at the POM.xml to see what they are).
If you happen to have any dependencies that conflict with the other JARs that included with the core test actor binaries, you can apply a technique called shading to "hide" the conflicting classes under a different package name. Most of the times you're not going to need this, but if you do and you get stuck let me know and I'll give you some pointers.
Here's sample project that demonstrates how to build an OpenTest extension that creates a couple of custom keywords: https://github.com/adrianth/opentest-extension-sample
And here's an extensive video tutorial about creating custom OpenTest keywords: https://getopentest.org/tutorials/custom-keywords.html

Why there are no stubs for interfaces in Microsoft.Fakes

I'm about to use Microsoft.Fakes in my unit tests. I read a tutorial where Microsoft.Fakes creates a stub for an interface (implementred inside the solution), but in my solution stubs are available only for classes.
Can you tell me what should I do to get stubs also for all the intercaes. Both interfaces and classes are defined as public.
Fakes generates stubs for both classes and interfaces by default. You may have bumped into one of the current limitations, which is causing Fakes to skip your interface. To troubleshoot,
open the .Fakes file and set Verbosity attribute of the Fakes element to "Verbose"
open TOOLS -> Options -> Projects and Solutions -> Build and Run and change MSBuild output verbosity to "Detailed"
build the project that contains the .Fakes file
open the Output window and search for the GenerateFakes task; review its output for information that explains why a particular interface was not stubbed.
In the upcoming Quarterly Update 1 of Visual Studio 2012, this information reported as warnings in the Error List window, regardless of the logging settings, which should make troubleshooting much easier.
You may also not have drilled down to the proper namespace. The Fakes are generated in the same namespace as the interfaces are in in your assembly under test. So, for example, if you're testing MyApp.Validators.IRequestValidator, in your unit test, you'll have to use new MyApp.Validators.Fakes.StubIRequestValidator() as opposed to new MyApp.Fakes.StubIRequestValidator().

How to do post-build modifications in an Eclipse builder

I'm currently working an Eclipse plug-in to provide iPOJO manipulation support.
The principle of iPOJO is to modify the .class files generated by the Java compiler to inject some methods and to add/update an entry to the Manifest.mf file.
Currently, my plug-in provides a project Nature and adds a Builder, added at the end of a project builder list, that calls the iPOJO Manipulator.
I use it on PDE projects.
The complete process works but I have a problem :
When my builder has finished its job (and the building process), the whole building process restarts, erasing the output folder and calling my builder again.
If I don't add a safety trick, it makes the building process loop over and over.
As I work on IResource, an IResourceDeltaEvent must be sent at the end of the building process, so I think the best way to avoid that kind of problem is to hide the fact that the resource has changed.
To be clear, I'm looking for a way to modify the class files after a PDE build, without inducing a new build, and without disabling the workspace auto-build property.
Thanks for answers.
I am a little unclear as to what you are describing.
You mention that you want this to work for PDE builds, but PDE builds happen largely outside of the workspace using ant scripts. They do not use IResource, Builder, or IResourceDeltaEvent.
I am guessing that you don't really mean PDE builds, but rather the building of plugin projects inside of the workspace.
In general, Eclipse (JDT in particular) expects that it has complete control over the output folders. However, there is an option in Preferences -> Java -> Building -> Output Folder called "Rebuild class files generated by others". Ensure that this is disabled. Eclipse should not try to rebuild class files that you touch. If your builder only touches class files then it will not trigger other builds after it changes the class files. The only thing is that you need to be careful not to compile things twice (and I think this is the problem that you are describing).
Alternatively, it may be easier for you to implement a CompilationParticipant (and the org.eclipse.jdt.core.compilationParticipant extension point). This will allow you to know exactly when JDT calls a compilation and exactly what it compiles.
Additionally, you will be notified of reconcile operations (ie- changes in working copies that have not been saved). This may be useful for you if you wanted to manipulate files as-you-type.

any msbuild file parsers available?

I am looking for an MSbuild file parser. Currently I have written my own that is not complete... but I feel like I am reinventing the wheel building something that surely exists already.
Microsoft.Build.Construction.XXX in microsoft.build.dll (version 4.0+) is a "raw" parser of MSBuild files. It is powerful and complete and analogous to the XML DOM. It works on a single file, doing no evaluation. It's useful for example when you want to run a script over a tree of projects to edit them in some way, perhaps to add a common import statement.
Microsoft.Build.Evaluation.XXX works on evaluated projects -- ie., with all the properties evaluated, imported files pulled in and so forth. It's useful in a development environment - you can read off the files and properties in the project, add new files and so forth. Visual Studio uses it for this purpose.
Before 4.0, there was a completely different, much more limited, and less complete object model in microsoft.build.engine.dll. It still ships with 4.0 but cannot handle some 4.0 syntax. It is deprecated.
I designed and implemented these so I'd be interested in feedback if you have any.
Some info I have found here... http://social.msdn.microsoft.com/Forums/en/msbuild/thread/b3db4d7c-b7d1-4958-9145-bfd34cc75320
In addition there is a small projects with some highlevel samples: http://code.msdn.microsoft.com/msbuildho
using Microsoft.Build.Construction;
using Microsoft.Build.Evaluation;
using System.Linq;
class Program
{
static void Main(string[] args)
{
Project testProj = new Project();
testProj.Xml.AddTarget("BuildProjects");
foreach (ProjectTargetElement pti in testProj.Xml.Targets.Where(pti => pti.Name == "BuildProjects"))
{
pti.AddTask("MSBuild");
}
testProj.Save(#"C:\testProj.proj");
}
}