Jump to content

Community scope "unfriendly" to password protection -- bad design decision?


Recommended Posts

While trying to distribute two classes with password-protected class members, where the first Class A has friended Class B, I'm getting the following error:

"The first time you establish access to a community scoped item in a password-protected library, you must enter the password for that library. This can prevent users from replacing a friended class on disk with another class of the same name. Enter the password for the locked library in the Project Library Properties dialog box."

Does this imply that it's a bad design decision to distribute password protected libraries that have community-scoped members and friended libraries?

Link to comment
Does this imply that it's a bad design decision to distribute password protected libraries that have community-scoped members and friended libraries?

I'd say it's just showing us the weakness of the by-name tethering that occurs between classes. Maybe it's time (for NI) to consider having something else idenitify classes to each other - perhaps some kind of GUID? We'd, of course, need some way to override it to be able to continue to distribute additional classes as plugins, but I'm thinking the name and prototype of the classes is a little too restrictive.

  • Like 1
Link to comment
Does this imply that it's a bad design decision to distribute password protected libraries that have community-scoped members and friended libraries?

I'm pretty sure I know what the answer will be from a certain NI employee whose name starts with Aristos and ends with Queue...

To be clear: there's no lvlib protecting the actual classes correct? It's just two classes with password protected member VIs?

Link to comment

I'm pretty sure I know what the answer will be from a certain NI employee whose name starts with Aristos and ends with Queue...

To be clear: there's no lvlib protecting the actual classes correct? It's just two classes with password protected member VIs?

Errmmm... yeah, about that (blush)

My first attempt at distributing with a "master LVLIB wrapper" was a dismal (personal) failure. Performance fell through the floor. Trying to pull classes back out of the LVLIB caused massive project-wide corruption in several classes. I'm pretty sure this initial attempt was my own fault... which essentially consisted of selecting a few dozen classes and dragging them all into an LVLIB at once (don't try this at home, kids). Perhaps a more gradual, graceful approach to building the LVLIB would have been more successful. But another technical hiccup would have involved the desire to lazy-load individual classes, and to my understanding the "master lvlib wrapper" would cause them all to load at once.

I still have my eye on LVLIB and even Packed Project Libraries as a distributable, but finer points such as this must be set aside for now. That was a long answer for your simple question, but "yes", I'm just trying to distribute two naked classes with a one-way friendship relationship.

And the current workaround: change scope of those methods from "Community" to "Public".

Link to comment
I'm having a separate GChat about this issue, and will copy what I just wrote moments ago: "the main prob is that filenames (rather than embedded GUIDS) are used as identifiers in class hierarchies. it's frustrating. same thing bites you with Dynamic Dispatch VIs -- they must have the same filename (which I personally find annoying)... filenaming convention should be abstracted from class functionality"

So, I think we're independently coming to the same conclusions here, crelf :yes:

What can I say? Great minds think alike. Although, for the public record, I thought of it first :P

*** EDIT: and this is not a bash against the current convention, I'm sure it exists for good reason. It's just that I'm running into problems, and just trying to flesh out the best practice ***

Agreed. This schema, like all such things, are evolutionary.

And the current workaround: change scope of those methods from "Community" to "Public".

You're right in that it's a workaround, but I wouldn't call that a solution.

Link to comment

You're right in that it's a workaround, but I wouldn't call that a solution.

Quite true. What I'm doing is not unlike the Flyweight Pattern, where the Flyweight friends the Flyweight Factory. The Flyweight would ostensibly mark many of its core methods as private, but since the FlyweightFactory (and only the FlyweightFactory) needs access, they can't be private. Friending seemed like the right implementation strategy (Inheritance is just wrong, and publicizing methods feels icky), but is incompatible with password-protecting the libraries.

So, the "icky solution" stands for now, but I'm up for re-evaluating design decisions for a better solution.

***EDIT: And again, to ensure minimal feather rufflage -- the title Community scope "unfriendly" to password protection -- bad design decision? was meant to ask if *I* am making a bad design decision; not to ask if it was a bad design decision by LabVIEW to not allow friending between password-protected classes. :P ***

Edited by JackDunaway
Link to comment

I'd say it's just showing us the weakness of the by-name tethering that occurs between classes. Maybe it's time (for NI) to consider having something else idenitify classes to each other - perhaps some kind of GUID?

I realize it's not completely analogous, but I think by-name tethering is reasonable since it's consistent with other (text-based) languages that require that functions which override each other have the same name.

Link to comment

Well, friends/community wasn't actually my feature, but I did have a heavy participation in its design.

> Does this imply that it's a bad design decision to distribute password

> protected libraries that have community-scoped members and friended libraries?

No. As a matter of fact, this is meant to facilitate doing this.

Friendship is a tight bond between two modules. Friendship designates one other module has having privileged access to the other module. It allows the two modules to be distributed independently, but when the two meet up, they can interact.

The password protection signs the befriended library so that no other library can claim to be the friended library.

CRelf suggested that this is "showing us the weakness of the by-name tethering that occurs between classes." Quite the contrary -- this creates a linkage that is not by name but is by signature. Without the password, you can replace the friend freely.

Link to comment

> Does this imply that it's a bad design decision to distribute password

> protected libraries that have community-scoped members and friended libraries?

No. As a matter of fact, this is meant to facilitate doing this.

Wait... whaaaaa? "Facilitate" is like the opposite of what happened here :blink:

Link to comment

My first attempt at distributing with a "master LVLIB wrapper" was a dismal (personal) failure. Performance fell through the floor. Trying to pull classes back out of the LVLIB caused massive project-wide corruption in several classes. I'm pretty sure this initial attempt was my own fault... which essentially consisted of selecting a few dozen classes and dragging them all into an LVLIB at once (don't try this at home, kids).

Been there, done that.

I almost totally wrecked a LVOOP project by trying to add then to lvlibs. A single mistake (I don't actually know WHAT the mistake was) led to all mixed-up relationships and a profusely cursing programmer.

I'm wary of lvlibs since.

Shane

Link to comment

Been there, done that.

I almost totally wrecked a LVOOP project by trying to add then to lvlibs. A single mistake (I don't actually know WHAT the mistake was) led to all mixed-up relationships and a profusely cursing programmer.

I'm wary of lvlibs since.

Shane

Ditto. I now have an aversion for lvlibs and only use them to control access to sensitive data.

Link to comment

Ditto. I now have an aversion for lvlibs and only use them to control access to sensitive data.

The funny thing about this statement is that .lvclass files ARE .lvlib files. Class LVClass inherits from class LVLibrary in the C++ code. So using classes means you're not avoiding libraries (same with XControls). But I'll accept that you're avoiding using sublibraries. Having said that, pretty much all of my work is done with an outer library around a set of classes. I work with the sublibraries heavily. If your burn came with LV 8.5 or earlier, I understand, but for the most part, things work these days (as long as you aren't trying to edit VIs that are already in vi.lib, but that's a bug that I'm probably the only user who encounters it).

Wait... whaaaaa? "Facilitate" is like the opposite of what happened here :blink:

Then, with minimum sarcasm, I say you're doing it wrong.

You should be able to create both modules and then distribute them independently. There's a bug in VI Package Manager that gets in the way of doing this with VI Packages (it insists on packaging the friended library in with the friending library because it does not recognize the weakened dependency relationship), but ignoring that, it should work just fine.

What you cannot do -- and maybe this is what you meant when you said "distribute" -- is *develop* them independently. As I said before, friendship is intended to create a coupling between modules. You can almost think of them as a single module that can be loaded into memory in parts. But they have to be created with full knowledge of each other.

[specifically for Jack's architecture]

I think what you want is this:

Create FlyFactory.

Create FlyPlugInBase. Add FlyFactory as a friend. Define some community scope members for FlyFactory to call. Those members wrap some protected scope members. Distribute both FlyFactory and FlyPlugInBase together.

Your users can inherit from FlyPlugInBase and override the protected scope members. FlyFactory always invokes through the FlyPlugInBase interface.

Link to comment

The funny thing about this statement is that .lvclass files ARE .lvlib files. Class LVClass inherits from class LVLibrary in the C++ code. So using classes means you're not avoiding libraries (same with XControls). But I'll accept that you're avoiding using sublibraries.

Yes, I'm aware. This is part of the frustration because I truly don't know why these problems arise and any small understanding of the matter I have is muddled with contradictions. But I don't wish to derail the thread.

With regards to Jack's issue, I can't say I've observed it. However does it not stem from how the password protection mechanism interacts with friendship? I believe the application of friendship here is truly one of the defining case studies-- I have used it in similar factory patterns.

I can't attest to how Jack was trying to distribute his code, but it would seem to me that for him to do so the password also needs to be available? How is he doing it? Is it wrong? Is there not another way? I'm curious to know how to do what Jack is trying to do. Wanting to distribute password protected VIs is something I understand, and knowing if having the VIs couple via friendship prohibits this is something to file under the "good to know" category if it is indeed true.

Link to comment

The funny thing about this statement is that .lvclass files ARE .lvlib files. Class LVClass inherits from class LVLibrary in the C++ code. So using classes means you're not avoiding libraries (same with XControls). But I'll accept that you're avoiding using sublibraries.

Right, yeah, to qualify, it's sublibraries that I ended up avoiding, for three reasons: 1) Edit-time performance 2) Crazy corruption and linkage problems 3) Architecturally -- to my understanding, loading a LVLIB member loads all the members, and I want members to be loaded ad hoc (lazy-loaded). The main reason I was investigating LVLIB is as an intermediate step to later investigate Packed Project Libraries, which *might* be acceptable in the third category (loading performance) -- just need to benchmark to test the theory.

You should be able to create both modules and then distribute them independently. There's a bug in VI Package Manager that gets in the way of doing this with VI Packages (it insists on packaging the friended library in with the friending library because it does not recognize the weakened dependency relationship), but ignoring that, it should work just fine.

What you cannot do -- and maybe this is what you meant when you said "distribute" -- is *develop* them independently. As I said before, friendship is intended to create a coupling between modules. You can almost think of them as a single module that can be loaded into memory in parts. But they have to be created with full knowledge of each other.

OK, I may have been inappropriately attributing this deficiency to lvclasses; I'm co-developing the classes (so we're OK there -- this friendly signage is probably occurring) and distributing using VIP (so here may be where the bug is introduced). The password protection is not existent in development; it's applied with VIPB. (I've alerted Michael of this thread, to weigh in)

To conclude, it's possible that I could further investigate at an academic level by creating a source distribution (rather than VIP) just to confirm password protecting is not a LV native hurdle to friendship; but this is kinda low on my priority list right now. (publicizing the few methods and moving along is way less painful)

[specifically for Jack's architecture]

I think what you want is this:

Create FlyFactory.

Create FlyPlugInBase. Add FlyFactory as a friend. Define some community scope members for FlyFactory to call. Those members wrap some protected scope members. Distribute both FlyFactory and FlyPlugInBase together.

Your users can inherit from FlyPlugInBase and override the protected scope members. FlyFactory always invokes through the FlyPlugInBase interface.

Yeah, but the one part left out of this sequence is password protection prior to distribution.

Once the two co-developed classes were password protected and co-packaged via VIPB, then installed to another machine via VIPM, FlyFactory was broken since it called community members of FlyPluginBase, since FlyPluginBase could not identify FlyFactory as a friend since FlyFactory is password protected.

To be clear, this is the problem I attributed as a LVClass deficiency, but you're saying it could be a VIPB issue.

Link to comment

So it seems that Jack is having a problem building a package with Friend Classes and applying password protection using VIPM. VIPM applies passwords to VIs and libraries using standard LabVIEW VI Server calls so not sure what the problem is. I've filed this as an issue that I need to look into and will probably be calling on NI for validation.

Link to comment

I've filed this as an issue that I need to look into and will probably be calling on NI for validation.

Thanks, Mike. Again, this lower-priority for me, a somewhat esoteric bug with a simple workaround, so don't twist any arms too hard for the sake of this thread ;)

And as a final update -- I created a source distribution and did not see this error (it only happens with VIPB) -- though I'm certainly not beyond ruling out my own process error along the way that results in these errors.

Link to comment
I realize it's not completely analogous, but I think by-name tethering is reasonable since it's consistent with other (text-based) languages that require that functions which override each other have the same name.

Sure, and I don't think anyone's arguing that it was a poor design decision: just that maybe it doesn't quite support all the use cases we're coming up with now.

The password protection signs the befriended library so that no other library can claim to be the friended library.

CRelf suggested that this is "showing us the weakness of the by-name tethering that occurs between classes." Quite the contrary -- this creates a linkage that is not by name but is by signature. Without the password, you can replace the friend freely.

Well, I think that calling the password a signature is a little weak. I mean, I guess you could think of it like that, but if you're going to have a signature I think it should be a signature that's separate from the password. Jack's usecase shows the weakness of having them be the same thing.

Link to comment
Yeah, but the one part left out of this sequence is password protection prior to distribution.
Ah... yeah, that's going to be a problem. To the best of my knowledge, assigning the password to the library really has to be done in the original source code for this all to work. You don't have to apply the password to all your VIs, just to the library, if that makes it easier to do development. I don't think there's a workaround involving VIPM at this time.

Well, I think that calling the password a signature is a little weak. I mean, I guess you could think of it like that, but if you're going to have a signature I think it should be a signature that's separate from the password. Jack's usecase shows the weakness of having them be the same thing.

It's the password that both creates the need for a signature and provides the basis for the signing. We didn't want a signature link when there wasn't a password as that created issues with source code control during development.

So it seems that Jack is having a problem building a package with Friend Classes and applying password protection using VIPM. VIPM applies passwords to VIs and libraries using standard LabVIEW VI Server calls so not sure what the problem is. I've filed this as an issue that I need to look into and will probably be calling on NI for validation.

Mike: The problem is that Jack is building two separate packages that need to be built at the same time from the same in memory source. When the password is applied to the first library, a GUID is generated as part of the signature. When the second library is built into a package, presumably you apply the same password to the first library (and here we run into the bug I reported against VIPM that friends need to not be built into the friended package and vice versa), but the GUID that gets generated is a different GUID, so the signatures do not match.

What has to happen -- and I realize this is a radical change for VIPM -- is that you load the source for both libraries into memory, apply a password to the first library and then output *both* packages without unloading from memory in between.

Link to comment

Nope - two classes, from the same lvproj (co-developed), built into the same package, with the same VIPB build produces the error.

Ok... I had read your earlier posts about developing from different developers and plug-in distribution wrongly then.

In that case, I do not know where this is coming from. Does it work when you apply the password in source code (actually save the libraries) and then build the VIPM? That right there will tell us a lot about whether this is a LV bug or somehow a VIPM bug (like VIPM saving files early in the process and not resaving them when they get a later docmod).

Link to comment
  • 10 months later...

I'm encountering this exact issue when test installing my toolkit in LabVIEW 2013. Built in VIPM, I get this error when first loading the newly installed library into memory. LabVIEW first asks me for the password for the various libraries, but it can't be provided so I end up with the error mentioned in the original post attributed to numerous VIs.

 

I've opened a support request with JKI as this is a known issue with VIPM, but I wonder if there's any advice I can get here on how to circumvent this issue? Or why I only see the error in LabVIEW 2013?

 

I'm quickly trying to catch up with the thread content (I'm not a formally trained OOP developer like some you folks so I'm just about treading water here), but from what I understand I can avoid this by:

1. Password protecting my source in LabVIEW, not VIPM. This would mean careful cloning of the Project before building it.

2. Avoiding the Friend relationship, and exposing functions as Public to ensure friend classes (and XControls) can access them. Disagreeable, given I'm trying to protect content.

Link to comment
...any advice I can get here on how to circumvent this issue?

...

I can avoid this by...Avoiding the Friend relationship

 

Here we are a year later; I no longer consider Community scope as a tool in my API design toolbox, for reasons in this thread, but more importantly for reasons in this thread. Making the change from "Community" to "Public" caused more mental/academic anguish than practical problems (i.e., it felt improper and dirty, but I've yet to find even a single negative ramification).

Link to comment

Thanks for the reply Jack.

 

I no longer consider Community scope as a tool in my API design toolbox... Making the change from "Community" to "Public" caused more mental/academic anguish than practical problems (i.e., it felt improper and dirty, but I've yet to find even a single negative ramification).

 

Really? Maybe I'm missing something then? In my master library I have a bunch of classes, sublibraries (containing more classes) and XControls. I wish for some class functions not to be publicly callable so as to prevent end-users messing around, so I'm to choose from scope choices of Community, Protected or Private. Private is for callers within the class itself. Protected is similar, but also accessible to child classes. Community (and this is from the LV Help) "The item is visible when users view the LabVIEW class. Only friends and VIs within the project library can call community VIs.". Well this is what I need for my class VIs, because my XControls are within the owning LabVIEW library and listed as Friends of the class(s). If I make these class VIs public I surely expose them to the end-user?

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.