Recently I fixed a bug on module A which will keep update from vendor and I can't directly modify module A.
So I want to build a module B to override module A.
What files i want to override
/etc/di.xml (Modify)
/Model/ResourceModel/Log/Grid/Collection.php (New create)
/Model/ResourceModel/Log/Log.php (Modify)
/view/adminhtml/ui_component/xxxxxxxx_listing.xml (Modify)
What is the best way to do it? Thanks.
Create a module and inside the di.xml for it you can set <preference for> to override a class that is defined somewhere else. Like:
<preference for="Original\Module\Model\ResourceModel\Log\Log\Log" type="Your\Module\Model\ResourceModel\Log\Log" />
I believe any changes on di.xml should be able to override the di.xml on other modules when your module if loaded after the other module. Same with the xxxxxxxx_listing.xml , if you place it under the same path it is in the other module, it will go ahead and override.
Adding the original module as a dependency to yours would ensure that your module is loaded after. So your module.xml would have a similar part inside it:
<sequence>
<module name="Original_ModuleName"/>
</sequence>
Hope this helps.
Related
I have a deployment that calls javax.crypto.SecretKeyFactory.getInstance.
The class javax.crypto.SecretKeyFactory appears to load correctly, but when the method tries to create an instance it throws a NoClassDefFoundError on sun/security/jca/GetInstance
Looking at the OpenJDK8 sources shows that relevant javax.crypto.SecretKeyFactory constructor refers explicitly to a method in sun.security.jca.GetInstance, so it's normal that it tries to load it.
What's odd is that both javax/crypto/SecretKeyFactory.class and sun/security/jca/GetInstance.class are present in /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.91-1.b14.el6.x86_64/jre/lib/rt.jar but that only the former is found by the classloader.
What is the jboss module classloader playing at and how can I get it to stop it?
Thanks for suggestions.
Not all JDK classes are exposed to a deployment by default. If your deployment uses JDK classes that are not exposed you can get access to them using jboss-deployment-structure.xml with system dependencies:
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.1">
<deployment>
<dependencies>
<system export="true">
<paths>
<path name="sun/security/jca"/>
</paths>
</system>
</dependencies>
</deployment>
</jboss-deployment-structure>
Another alternative you can import the whole system module adding the following line to MANIFEST.MF:
Dependencies: system
Ref: Class Loading and Modules
In your JBoss installation, go to directory modules/sun/jdk/main and edit the module.xml file there. In <dependencies>/<system>/<paths> add an element <path name="sun/security/jca"/>. Restart your JBoss instance and retry.
I finally fixed my problem, though not quite in the ways suggested above. I wouldn't have got there without the help though (thanks guys).
I did manage to fix the sun/security/jca access problem but it then threw up another problem of a similar type, but with a javax class. I found an ugly fix for that by removing a jar from module org/jboss/genericjms and letting the jdk version get picked up, but I felt that that was playing around too much with stuff that I couldn't predict the consequences of.
The fix I have finally settled on is to put the provided jar that references javax/crypto/SecretKeyFactory in a new module all of its own and then to pull in the classes it needs via:
<system export="true">
<paths>
<path name="java/sql"/>
<path name="javax/crypto"/>
<path name="javax/crypto/spec"/>
<path name="javax/crypto/interfaces"/>
<path name="javax/management"/>
<path name="javax/security/auth/login"/>
<path name="sun/security/jca"/>
<path name="org/ietf/jgss"/>
</paths>
</system>
in the module.xml. When I reference this new module from my code it works (I pulled it in by making it a global module in standalone.xml in fact).
Problem solved. Though I have to say that after this experience of the jboss modular class loader, give me a hierarchical one any day.
Thanks again for the help.
Problem
Is there any way Codeserver accept more than one dir in the -src flag?
Details
I'm trying to separate my source code into folders like this:
src
widgets
utility
main
I got the regular dev mode to compile my code via the following *.gwt.xml files:
src/MyProject.gwt.xml
<module>
<inherits name='com.google.gwt.user.User' />
<inherits name="com.my.project.Widget"/>
<entry-point class="com.my.project.Test" />
</module>
widgets/Widgets.gwt.xml
<module>
<inherits name='com.google.gwt.user.User' />
<inherits name="com.my.project.Widgets"/>
</module>
But every time I try to run in the Codeserver (SuperDevMode), it will say it can't find classes in com.my.project.Widgets package.
I'm running SuperDevMode using the following arguments:
-src src/ com.my.Project.MyProject
But I'm guessing I need something like:
-src src/ com.my.Project.MyProject widgets/ com.my.Project.Widgets
FYI
I know you can organize the classes using packages but I would prefer to have them in separate source folders, so later on I can easily repackage them into separate jars.
Update
Just tried adding the [module]:
-src src/ com.my.Project.MyProject com.my.Project.Widgets
Didn't work :(
Just pass -src as many times as you need it:
-src src/ -src widgets/
The modules comes last on the command line, and are looked up in all source folders and the classpath:
-src src/ -src widgets/ com.my.Project.MyProject
Note that only modules with an <entry-point> (or inheriting a module that has an <entry-point>) can be passed that way on the command line; without entry-point the module is only a "library" to be inherited by other modules, not an "application".
Note, you could also just add all your source folders to the classpath, instead of using -src.
I'm moving over to a new computer, and in the processing I'm creating new Intellij 12 projects from my git source.
I have a gwt module file containing the following:
<!-- Other module inherits -->
<inherits name="com.google.common.collect.Collect" />
<inherits name="com.google.common.base.Base" />
<inherits name="com.bdl.message.Message" />
<inherits name="com.bdl.universal.Universal" />
<inherits name="com.bdl.appengine.AppEngine" />
<inherits name="com.bdl.gwt.BdlGwt" />
<inherits name="com.google.gwt.inject.Inject"/>
The com.bdl.* entries are from another library I've written and I have their jar files (and sources) in the module dependencies. I can confirm that removing those dependencies causes the corresponding inherits nameto turn red, indicating an error.
I also have as a dependency, a global library Guava (GWT) which contains:
classes:
guava-14.0-rc2.jar
sources:
guava-14.0-rc2-sources.jar
guava-gwt-14.0-rc2.jar
javadoc
guava-14.0-rc2-javadoc.jar
But despite this, the inherits for Collect and Base are red and the GWT compiler fails, saying it can't find Collect.gwt.xml.
On my old system I have an Intellij 11 project, which is set up the same way (there must be some difference somewhere, but I've been looking for hours to find it and can't)
That also has the same library as a dependency, and the inherits lines in my app's module are still red, but the GWT compiler succeeds, finding the Collect.gwt.xml right where it should be, at:
jar:file:/[path-to-guava]/guava-gwt-14.0-rc2.jar!/com/google/common/collect/Collect.gwt.xml
There must be something simple and stupid that I'm missing, but I can't find it.
You probably need to add guava-gwt-14.0-rc2.jar to your dependencies. Notice that the name has -gwt- embedded in it and you said that you have just these as dependencies:guava-14.0-rc2.jar sources: guava-14.0-rc2-sources.jar guava-gwt-14.0-rc2.jar javadoc guava-14.0-rc2-javadoc.jar
You can check that the jar is the appropriate one because when you open it (it is just a zip file) you should see the Collect.gwt.xml file somwhere within.
I have a class library with numerous projects, each referencing each other, written in C#. This is a common library that I share with other projects. I have recently changed the mechanism that the library is shared to be via nuget. So for each project within the library, I have a post build event to create a nuget package eg.
"$(SolutionDir)\NuGet.exe" pack "$(ProjectPath)" -o "$(SolutionDir)\Packages"
This works nicely. It pushes the package to a shared folder in the file structure and the consuming project installs it from there. All projects packages are pushed to this folder.
I have ran in to a problem though. Lets say my library creates package X and Y. X has a reference to Y in the class library. In the consuming application, I need to use X, when I install it, it doesnt install the ddl from Y. I also need to install package Y. How can I set it up when package X is created, it also includes the necessary dlls's from package Y, without having to explicitly install it?
in the nuspec file of package X you can specify package Y as dependency
<dependencies>
<dependency id="Y" version="1.0" />
</dependencies>
More options around dependency can be found here http://docs.nuget.org/docs/reference/nuspec-reference#Specifying_Dependencies
For specifying files you could use
<files>
<file src="bin\Debug*.dll" target="lib" />
<file src="bin\Debug*.pdb" target="lib" />
</files>
More details here http://docs.nuget.org/docs/reference/nuspec-reference#Specifying_Files_to_Include_in_the_Package
I have a generic common.xml file that holds a number of generic nant targets that are re-used among multiple builds. What I want to do is 'override' some of these nant targets and include additional steps either before or after the existing target is executed.
Are nant targets used from the current file first? ie. If i create a nant target in the current buildfile with the same name as a target in an included file does that one get called and the included one ignored? If that's the case I can just do and call the included target but it would seem like then that would be a recursive call rather then to an included task.
Thoughts?
I had the same question (and found the same results), but I also found a workaround. Allow me to illustrate with an example.
You have a ProjectFile.build and a CommonFile.build. Let's say you want to overwrite a target called "Clean".
You would need to create a new file (call it CommonFile_Clean.build) which contains:
<?xml version="1.0"?>
<project>
<target name="Clean">
<echo message="Do clean stuff here" />
</target>
</project>
In CommonFile.build, you conditionally include CommonFile_Clean.build:
<?xml version="1.0"?>
<project>
<echo message="checking Clean definition..." />
<if test="${not target::exists('Clean')}">
<echo message="Clean target not defined." />
<include buildfile="CommonFile_Clean.build" />
</if>
</project>
In ProjectFile.build, you can either define the Clean target (in which case CommonFile_Clean.build will not be used) or use the default implementation as defined in CommonFile_Clean.build.
Of course, if you have a large number of targets, this will be quite a bit of work.
Hope that helps.
No, I've just tried it for you, as I have a similar set-up, in that I have all of the build targets we use in a commonFile.build and then use the following code to bring it in...
<include buildfile="../commonFile.build"/>
In my newFile.build (that includes the commonFile.build at the top of the file), I added a new target called 'build', as it exists in the commonFile, and here's the error message you get in response...
BUILD FAILED
Duplicate target named 'build'!
Nice idea, probably bourne of OO principles, but sadly it doesn't work.
Any good?