I want to nicely recognize situation when maven plugin is executed from maven project or not, because I need different default parameters when execution is outside of maven project.
I can inject #Component MavenProject project into plugin Mojo, but this is setted to test:test:jar:1 when there is no pom.xml.
I can inject base dir #Parameter(defaultValue = "${basedir}") File baseDir and check for pom.xml file, but this smells (with polyglot maven there is no pom.xml anymore).
How to check if project is executed inside or outside maven project?
I have specific goal and I want to use this same goal for both situation.
I feel the question is not answered enough. My proposal is:
#Component
private MavenSession mavenSession;
boolean insideMavenProject = mavenSession.getRequest().isProjectPresent()
The important thing is that you clearly make a decision which goal should be used from CLI only and which should be used within the pom file... The basic decision can be made by using the following:
#Mojo( name = "xxxx", requiresProject = true,... )
so the requiresProject means you need to have a pom.xml which means no calling via CLI.
If you omit this you can give the opportunity to use a goal from CLI. So best is to use one goal which is intended for calling from CLI and an other goal which is intended to be used from the pom.xml ..
Furthermore to inject a MavenProject you should do this like this:
#Parameter( defaultValue = "${project}", required=true, readonly=true)
private MavenProject project;
cause a MavenProject is not a #Component. Apart from that i don't understand your information about test:test:jar:1 always...and what i'm interested in is what kind of plugin are you trying to write?
Related
I have some Java code that is currently packaged in the BEA Workshop for WebLogic Platform.
My task is to migrate the structure of the project (without actually touching the code) to a maven structure to be packaged from command line (or from eclipse m2e).
Problem is, the code has some annotations like this:
#WebService(serviceName = "Cancelacion", targetNamespace =
"http://www.banamex.com.mx/OtorgamientoPension/cancelacion")
#WLHttpTransport(contextPath = "OtorgamientoPension", serviceUri =
"cancelacion", portName = "cancelacionSOAP")
#Policies({
#Policy(uri="policy:Wssp1.2-Wss1.0-X509-Basic256.xml", direction = Policy.Direction.inbound),
})
public class CancelacionPortImpl implements CancelacionPort {
...
}
That create some configuration inside the war (a mysterious meta-inf inside the web-inf and plenty of xml).
Please notice the #Policies which is from a WebLogic library. It creates some security-related config and that's (alongside the ws stuff) is what i want to generate.
Is there a way to process this from maven?
EDIT
So far I have tried with the weblogic-maven-plugin. It didn't work (also, due to internal policies, the not-so-straightforward way of installing this plugin is not an option).
I'm trying to find a vague reference a co-worker gave me about certain "jtools" compiler... but can't find anything that comes with that name and have some relation with WebLogic.
So the #Policies annotation is still a problem.
Right now I'm looking for a eclipse-plugin that does this, based on the premise that was the IDE who process that annotations.
For the wsdl issue, I find out that the namespace definition whas wrong. I corrected it and now it's working. I used the jaxb2-maven-plugin because I have no knowledge of jaxws-maven-plugin and I already had the config of the former.
Looks like you might need some Weblogic classes on your classpath. Short of uploading these to your own private Maven repository, you might consider checking out the Oracle Maven repository to find the Weblogic artifacts you need. Since these are likely container-provided jars (i.e. you don't need to package them in your war), you'll want to define them with a scope of "provided" in your dependencies, e.g. <scope>provided</scope>.
I would like to test that a spring
#Configuration class
can handle missing files on the classpath. E.g. when using PropertySourcesPlaceholderConfigurer. But this is just a specific example, the question is really about how to test classes that interact with the classpath (e.g. read a file located in src/main/resources in a maven project).
So in essence I would like to create a spring context where I control the classpath in the test set up code.
The test needs to be a JUnit test.
Hope below may help you
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath*:/testApplicationContext.xml"})
public class YourTestClass{
you have to create a spring context for your test and you can include the production one into it. you can replace classpath*: with a absolute location.
Regards, Rajib.
This work if it's a maven project:
move the classpath file that you want to test the absence from to a separate pom jar module, and include it wherever needed.
move the classpath test to a separate pom jar module named missing-classpath-file-test, but don't include the module with the file that you want to simulate as missing. I will be missing from the classpath only for that test.
When running missing-classpath-file-test, the file will not be on the classpath, and the error you need to reproduce is achieved.
Concerning the question on the comment bellow, with the class loaders that come with application servers and the one used on a junit test it's not possible to programmatically change the classpath.
I'm trying to write a plugin into a framework application (Joget). My plugin source looks something like this:
public class MyPlugin extends ExtDefaultPlugin implements ApplicationPlugin, ParticipantPlugin {
...
public void execute(){
...
SecurityContextImpl secContext = (SecurityContextImpl) WorkflowUtil.getHttpServletRequest().getSession().getAttribute("SPRING_SECURITY_CONTEXT");
}
}
When I run the plugin, I get the following exception.
java.lang.ClassCastException: org.springframework.security.context.SecurityContextImpl cannot be cast to org.springframework.security.context.SecurityContextImpl
I'm using Maven. Now since both have the same package name, I'm assuming I'm accidentally using the wrong package version in my plugin JAR (that contains the SecurityContextImpl class) than the one in the framework. But I've double-checked and it looks like I'm including the correct one in my plugin package.
Is there a way to see the classloader or source JAR of my class (e.g. using reflection in some manner)? Any other ideas on how to address this?
This type of java.lang.ClassCastException, where both classes names are equals, occur when the same class, or two class with the same name are loaded by 2 different classloaders.
I don't know Joget, but you are talking about plugin. Frameworks often load plugins in separate classloaders to ensure a proper isolation between them.
Since you say I've double-checked and it looks like I'm including the correct one in my plugin package., you may want to remove spring-security from your package, as it's probably already loaded by the framework classloader.
You're using Maven, so you may simply add <scope>provided</scope> to the spring-security dependency (but not sure, since we don't have your pom.xml)
I've got the same exception when I was running my plugin.
There are two cases in general:
1. The class is a local class.
And that is to say, there is no repository(groupId, artificateId, etc) to be deployed in the pom.xml of your plugin. The solution is, go the target folder and open the xxx-0.0.1-snapshot.jar file, then open META-INF/MANIFEST.MF, add the source file of that class /dependency/file.jar, then add the source jar to the dependency folder
Remarks: It is better to give a version of the your local file and add it as shown in your pom.xml to let it be found as src in your code.
<!-- your source jar need to be renamed as example-1.0.0.jar -->
<dependency>
<groupId>this.should.be.the.prefix.of.your.package</groupID>
<artificateId>file.name<artificateId>
<version>1.0.0</version>
<systemPath>${basedir}/lib/stclient_updated-1.0.0.jar</systemPath>
<scope>system</scope>
</dependency>
2. The class is a remote class with repository
I had this type of problem once because the repository is not correct, see also Maven Repository to find the official repository of the source.
I hope that it could help =)
Cheers
I am wondering what would be some suggestions for project / module organization given the following situation:
I have a project DomainObjects in which I have a class MyObject
In /src/test/java of DomainObjects I have the tests for MyObject
I have a project Client that depends on DomainObjects
I would like to add a ParameterSupplier called MyObjectTestSupplier class to provide test instances of MyObject for use by tests in Client.
It seems to make the most sense to provide MyObjectTestSupplier in the DomainObjects project. Here is my dilema...
if I put the supplier in src/test/java of DomainObjects it will not be available to Client.
I don't want to put it in src/main/java of DomainObjects because that means that JUnit would have to be included as a compile dependancy of DomainObjects and thereby be included in my production code.
if I put the supplier in some project DomainObjectsTest I have three options
put just the supplier is the test project but this means that tests in DomainObjects could not use this supplier.
put all the tests and suppliers for DomainObjects in DomainObjectsTest but that means that DomainObjects will be successfully compiled by maven even if tests fail
copy the supplier in both src/test/java of DomainObjects and src/main/java of DomainObjectsTest.
I thought about trying to make DomainObjectsTest a module of DomainObjects but that only works if the packaging for DomainObjects is pom which does not work here.
Thoughts? Suggestions?
EDIT: As an explanation, MyObject is a simple bean (just getters and setters) and I use the ParameterSuppier pattern for providing populated instances of beans. The supplier provides utility methods to easily create populated instances of the bean for use in testing. I do this so that I don't repeat this population code (or the mocking equivilent) throughout my project(s).
As the official Maven mini guide on this particular topic says you should publish a test artifact of the DomainObjects project into your local Maven repository (or anywhere you'd like or able to) and use the DomainObjects-X.Y-tests artifact as a test-scoped dependency in your Client project.
Publishing a test artifact is done by using the jar:test-jar goal of the Maven JAR plugin.
If you include this artifact as a test-scoped dependency in your Client project then any other project that depends on the Client project won't inherit your DomainObjects project's test artifact, because test-scoped dependencies are not transitive by default as stated by the official guide on Maven's dependency mechanism.
That is a bad design example what you're describing. Your unit test can't depend on external dependencies to be "unit".
What you need to do is to mock all dependencies and test only Client code. Use Mockito or another library of your choice to create mock instances of MyObject in client project according to what you expect this class to do. Test MyObject behavior in its own project - DomainObjects.
In mockito creating a mock is just :
import static org.mockito.Mockito.*;
...
MyObject myMock = mock(MyObject.class);
when(myMock.doWhatYouNeed(params)).thenReturn(whatYouExpect);
Edit:
Another ideas
Publish DomainObjects' tests as artifact of type test-jar as descibed here and use it as test-scoped dependency in Client. But this is quite ugly...
Nice design is :
DomainObjectAPI project with MyObject,
DomainObjectTestSupplier using DomainObjectAPI providing suppliers,
DomainObject using DomainObjectAPI for compile and DomainObjectTestSupplier for testing
Client using DomainObjectAPI, DomainObject for compile and DomainObjectTestSupplier for testing.
It's just an overkill.
I've read some questions here about how to set a property (most of them talked about the version number for an application) from a maven plugin.
It seems there's no easy way of doing this and the best solution I found is to have a filter.properties file which is updated from the plugin and used by the main pom file to filter the desired resources.
I tried another solution after I read this from the Maven documentation (Maven filter plugin):
Variables can be included in your resources. These variables, denoted
by the ${...} delimiters, can come from the system properties, your
project properties, from your filter resources and from the command
line.
I found interesting that variabled can be read from system properties. So, I modified my plugin to set a system property like this:
System.setProperty("currentVersion", appCurrentVersion);
However, filtered resources don't seem to read this value.
Could anybody tell me what's wrong with this approach?
UPDATE: I'm running my plugin in the validate phase.
Thanks a lot.
Don't set it as System Property, set it as Maven Project property
// inject the project
#Parameter(defaultValue = "${project}")
private org.apache.maven.project.MavenProject project;
// and in execute(), use it:
project.getProperties().setProperty("currentVersion", appCurrentVersion);
See:
Mojo Developer Cookbook
MavenProject javadoc
An edit suggested using Properties.put() instead of Properties.setProperty(). While technically, Properties implements Map, this usage is discouraged explicitly in the Properties javadoc.
Maven sets properties in initialize phase. I assume that in that phase maven loads system properties. And after that maven doesn't load system properties again. If you try to add a system property after this phase than it's not loaded.
Try to run your plugin in validate phase.