I've got a number of SMS providers, each in a separate directory in the file system. The main class inside each provider directory extends abstract class ProviderAbstract.php which is located elsewhere in the filesystem and outside the provider directories.
I want to make each provider a separate composer package so it can be developed, tested and deployed independently. The problem is the ProviderAbstract class that each provider extends... what is the best approach in this situation? having a copy of the class inside each Provider package isn't the solution.. what is the best approach to resolve this type of dependency..
Thanks in advance
I don't know if this is the correct way. If you have a log at e.g. Monolog or Swiftmailer, they all have the "Providers" inside their one composer package. They can develop one Provider without looking at the others, testing them and deploy the whole package afterwards. If you decide to put components so small into own composer packages, you will end up with much overhead.
However, if you want to go on with that, you could extract the abstract class into it's own composer package and have all the other packages have this as a dependency. This is the way the PSR3 logger interface is used.
Related
I an instant app with around 10 feature modules and one base feature. All of the modules build correctly except for one. If I don't have the layouts for this one feature included in the base feature then the module won't build. It states that the layout resources don't exist even though they are included in the resources directories for the feature module. Has anyone seen this? What can I do to resolve this? Thank you!
Yea it's annoying i had to do something similar. I appended feature's name to the package of feature. Let's say my base package is com.myapp.android, and i have a feature named "awesome", I gave "com.myapp.android.awesome" as package name of that feature. Then while importing the resources I simply did, com.myapp.android.awesome.R.id.login and it worked.
The issue was that I had the R imported from the curbside app base feature and not the feature module.
I'd like to include a resource file (e.g. some xml config file) in my bundle and make it visible to all other bundles in the container. Is it possible without using the Fragment-Host manifest header? I'd like this resource file to always be visible in the classpath of all bundles running alongside my bundle, even those that do not exist yet, but will potentially be added in future.
EDIT:
To clarify - that resource must be available passively, i.e. the other bundles should be able to find it in their classpath, and not by refering to any special API or service of my bundle.
Some more background - my environment is a bit messy but I have no control over it and cannot change its existing bundles. The only way I can modify it is by adding my own bundles. That environment includes several copies of the ch.qos.logback.classic bundle. When logback starts up, it looks for specific XML config files in the classpath. If it doesn't find any of them, then its default behaviour is to print everything to stdout with debug level. This environment was previously used to host a GUI application so it didn't matter that much before, but now I am trying to adapt it so I can use some of its functionality in headless mode. So now it becomes important to me to be able to configure it in such a way that only warning and errors are printed to the console.
In general, no you cannot do this. Class-space isolation is at the heart of OSGi, but you want to put a resource in the class loader of one bundle and make it visible to all other bundles. That's not OSGi, it's the global application classpath.
The only thing you can do to add to the internal classpath of a specific bundle is to write a fragment which attaches to that bundle. A fragment can attach to multiple host bundles, but only if those hosts have the same symbolic name, i.e. because they are different versions of the same bundle. See OSGi R6 Core Specification, section 3.14.
You did however state that the bundles you want to attach are all copies of ch.qos.logback.classic. If that means they all have that exact symbolic name then perhaps a fragment will work after all.
You can not change the classpath of other bundles this way.
What you can do is retrieve the classloader of your bundle from your bundleContext. You can give this classloader to another bundle to retrieve your resource.
ClassLoader cl = context.getBundle().adapt(BundleWiring.class).getClassLoader();
Another option is to give the other bundle the URL of the resource.
As long as the resource is on the classpath, any bundle can access the resource if it can get hold of the class loader of the bundle that contains the resource.
For example:
ClassLoader classLoaderOfBundleWithResource = ...
classLoaderOfBundleWithResource.getResourceAsStream("org/example/resource.xml");
From a maintenance and API point of view, I would not recommend exposing a resource that way. Java types are much better suited therefore. Instead, let the resource bundle export a class that gives clients access to the contents of the resource.
For example:
public class XmlDocumentProvider {
public InputStream openDocument() {
return getClass().getResourceAsStream("resource.xml");
}
}
Assuming that both the resource.xml and the XmlDocumentProvider reside in the same package, openDocument will return the resource content just like in the first example.
I am new to Eclipse plugin development, and I am trying to develop a plugin where I am required to load a class which is selected in the Navigator.
Can you please instruct me how can I load a class or create a classloader from eclipse plugin, to load a class in the eclipse workbench which is using my plugin.
Thanks in advance.
Regards
Gillani
You need to create a URLClassLoader. You may want it to be parented or not, depending on your security concerns. If parented by an OSGi bundle class loader, then the user will have access to all of the classes in that particular bundle and this may be a back door to the user getting runtime access to the entire Eclipse platform (and access the plugin registry and the OSGi services, etc). The user can also call System.exit(). This may not be a problem on a single user system, but it is something to think about, especially if the user may be downloading unverified scripts from the internet.
That being said, you need to do something like this:
Instantiate a URLClassLoader and add the URLs of the directories containing the class files you will want to load.
if you want the classes to have access to the Eclipse runtime, then set the parent loader to be
((BundleHost) Activator.getBundleContext().getBundle()).getLoaderProxy().getBundleLoader()
Add all of the directories corresponding to URLs where the user can load classes from. But, you must include all dependencies in order to load the classes.
This should be enough to load the classes you require.
I know this can be done as there are other modules out there that have this, but I'm just not getting it to work.
I have created a custom module for a DotNetNuke site. I want to be able to create a class object within the module to hold the information about that object. I can create the object and everything complies. But when I go to use the object in the code-behind it states that the object is not defined. I'm not really sure where to go from here.
This is the beginning of the View.ascx.vb :
Namespace Modules.VacationForms
Public MustInherit Class View
Inherits PortalModuleBase
This is the object class beginning:
Namespace Modules.VacationForms
Public MustInherit Class Vacation
I'm really not sure why this is not working. I did download another module code to compare and as far as I can tell everything is the same. Any help is appreciated.
Are you using a Web Site Project or a Web Application Project? The Web Application project will allow you to compile all of your code together (the only issue here might be the the Root Namespace setting in your project, but, assuming both classes are in the same project, that shouldn't be it). If you're in the Web Site project (e.g. developing directly in the DNN solution), then your code won't get compiled in the traditional sense, but will be on-demand compiled by DNN. It only does that for code behind files associated with requested controls/pages (e.g. your View.ascx.vb) and code files in the App_Code folder. I would guess that your hangup is that your Vacation class' code file isn't in the App_Code folder.
It looks you are not using the Web Application Project for module development. Easiest thing to do is install module development templates (from dotnetnuke.codeplex.com download starterkit package of your dnn version).
If your module is too simple and you don't want to do that, OR you don't want to install the templates in your pc, you can do following:
If you are using a vs version that is not using WAP by default, get the installation from web.
create a new folder for your dnn module in DesktopModules directory in root
add a new WAP project in that folder.
remove web.config from that folder, go to properties and point build output director to your dnn site's bin directory (../../bin will work most of the time)
Once you are done with that, all your code will start working as expected.
Good thing about this is, all your .vb and .ascx.vb files will be compiled in a single dll that you can distribute as a package easily.
Hope this helps
I've never had any problem with the basic gem tree structure, namely
bin (executables)
lib (source code)
test
...because I've always developed gems as libraries. However, I recently started to develop an application that ships as a gem.
This application has a "runner.rb" file (lib/mygem/runner.rb), that provides a method to run the application. The application is run from the bin/mygem file.
Now this bothers me. "runner.rb" is a file that is specific to our application, it is not a service or an API or any kind of support class for other to reuse (which is what library should be for, right?), yet its directory is "lib/mygem/runner.rb).
I've been reading a lot of definitions, and libraries are supposed to be support an application, not to be the application itself. We don't say "this is the library of my application", but "this is the source code of my application".
So my question is, why do we put the libraries AND source code in the same folder?
I hope I made my point clear, I'm sure there's a good reason behind this, and I'd be interested to hear your thought and to clear this out.
Thank you for reading this :)
After even further investigations, it turns out 'lib/' is called 'lib/' because it only contains definitions.
'bin' is a script that gets executed, like a 'main' function. Since it gets executed, no application logic should be in it, otherwise it's not easily testable.
Thus, all the application logic belongs to your application's library folder. The bin (main) file's only task is to instantiate your application's runner class and run it.