Having a "library" of jenkinsfiles - java

We have 1900 separate Java projects. At the moment, we thinking about introducing Jenkins. Many of the projects would need to have the same jenkinsfile, except for 1 or 2 parameters which need to be set.
In the Java projects, I would like to "import" jenkinsfiles, following the logic
Use jenkinsfile "Standard-Jar-Build" with parameters according to "project.properties"
What could be a way to have such a "jenkinsfile library"?

In the company I work for right now I created a set of jenkinsfiles that represent certain pipeline workflows. These workflows are generic and all the project specific configuration can be passed to the jenkinsfile using job parameters.
So the only thing projects have to do is "pipeline from SCM" and point to our script files and then customise is for their project using the available properties.
Also to keep the jenkinsfile small we also use the global library feature. We call it 'common' and it contains all kinds of methods that the jenkinsfiles can use.
Added bonus: everything in the common is automatically allowed, no whitelisting needed.

Related

IntelliJ DSL plugin provide completion of Java classes and methods

I'm attempting to write an IntelliJ plugin for a DSL which references Java classes and methods. The DSL is exposed in *.conf files within a Java project. A typical snippet of the DSL looks like this:
TASK taskClass=com.example.Foo taskMethod=someMethod;
I've been working through the IJ 'Simple' plugin tutorial to learn about plugins and am able to implement a fair bit of my own plugin. Currently, however, I'm stuck on trying to understand how I can provide auto-completion for the taskClass and taskMethod keywords. Having worked through the Simple tutorial all my completion shows is 'Hello'. Now I want to be able to extend my CompletionContributor to show java classes and methods that exist in the project. This doesn't seem to be addressed in the tutorial, but perhaps I'm just missing it.
What do I need, in order to do this? I would guess that there is already some cached info about all the existing java code in a project that my Contributor could leverage.
I think you are looking for the existing stub indices.
For example, to get all class names in your project, you can use
val classNames = JavaFullClassNameIndex.getInstance().getAllKeys(project)
When using indices - your own or already existing ones - it is often useful to use the Index Viewer plugin so you can have a look at which things are in which index.
To add it as a dependency of your plugin (so you don't have to install it manually each time you build your plugin) add the following to intellij block of your build.gradle.kts:
plugins.set(listOf("java", "com.jetbrains.hackathon.indices.viewer:1.19"))
It should appear as a tool window on the right.
Don't forget to remove it once you are done with debugging the indices.
I also found the PsiShortNamesCache which might be useful.

Is there any way to reorder projects in the package/project explorer in Eclipse?

I'm working on source code that is split across several projects with a specifically defined build order. I want to see the projects sorted by the build order so I can always tell which classes can be used in which projects. Does anyone know how to do this in Eclipse Kepler?
If you are not already using working sets in Eclipse, they provide a good way to organize your projects. The organization is single-level, rather than hierarchical, but you can group projects and then quicly select in the project explorer view settings whether you want the working sets to be shown or not. A potentially useful detail is that a project may be contained in multiple working sets, so that you can have multiple grouping criteria at the same time.
In your case, you could define a working set for each phase of your build, prefixing its name with a letter or number that would ensure its presentation in a specific order. Or you could define a working set for each set of projects with the same dependencies.
Alternatively, you might be able to just rename your projects appropriately. In many cases the project name itself is mostly cosmetic, although it is often used as a default in generated files.
In my opinion, however, the easiest way to "tell which classes can be used" is to just configure your project build paths correctly and let the editor do the rest. For me it is more natural not to use a class because it is not proposed for auto-completion or because any such use results in a compiler error, rather than explicitly checking the dependencies each and every time...
IMHO there is no such feature in eclipse. But you can use Resource Tagger plugin or Resource decorator plugin and filter the resources based on different conditions.

Packaging common code for better code reuse in java

I have two java projects that are fairly independent beside the fact that they share a common mysql database.
I wanted to refactor these project and extract everything regarding the common data layer. I am using jOOQ, so most of this layer gets autogenerated in my build. Beside that i then have a few common entity classes that are used in both projects.
what would be the best practice to separate this, so that any change can be done one place and still propagate to both projects? create a third java simple project with the common code? what would you do
I work on a distributed system, and multiple daemons need access to the same Postgres database via jOOQ. Since each daemon is its own Java project, I am in the same boat as you basically.
The solution I've been using is to create a third Java project as a Java Library. If you're using Netbeans you can just include it as a subproject dependency and any changes to the library project can be recompiled into the individual application projects.
One thing of note, you'll need to specify the jOOQ library jars in all 3 projects. In Netbeans its easy to specify a project's library directory, and have multiple projects share these dependencies. Netbeans will copy the dependencies at deployment time.
Edit:
The steps are basically:
create a master layout for system, IE:
/master-project/
/master-project/library
/master-project/software
/master-project/software/daemon1
/master-project/software/daemon2
/master-project/common
/master-project/common/utility1
/master-project/common/utility2
create third-party "library" bundles of {jar,src,docs} under /master-project/library.
create "application" projects under /master-project/software, making sure to tell Netbeans to only use third-party libraries under /master-project/library.
create "library" projects under /master-project/common, making sure to tell NB only to use third-party libraries under /master-project/library.
create a "library" for jOOQ code to be shared, as in step 4.
Each project is responsible for its own compile script (including generating jOOQ code, if desirable), and correctly specifying its dependencies out of /master-project/library, and /master-project/common.

Java preprocess phase

I'm writing a Java application that needs a lot of static data that is stored in many enum types. Since I would like an user-friendly way to customize this data using for example xml or json files but I'm not allowed to do it directly with enums I was looking for a way to elegantly do it.
Maybe a good solution would be to have a separate java program that reads the xml files and produces the java sources that are then compiled with the remaining part of the sources. My doubs is how to automatize this process in a stand alone way (eg ant?) and how to integrate it seamlessly with eclipse so that it is autOmatically done when I'm working with the project.. Does anything similar to what I'm looking already exists? Any suggestion to solve my problem?
Thanks!
If the items and the overall structure are somehow fixed (and what varies most is the values of the attributes), you could consider defining the enum with one entry for each of your items and let the enum populate its own constants with data read from an external source (XML / JSON) -- at load time or on demand.
Create a project whose sole job is to generate java from your sources.
Make sure that the generation phase is done by Ant.
Now, wrap this project into eclipse and use a custom ant builder, that calls the target in your already existing build.xml.
This is a standard part of our dev infrastructure, so this definitely works.
You can write a maven plugin that generates the code. There are some plugins that do that. It won't work automatically, but you can connect it to the standard maven lifecycle so it gets executed just before compile.
I just did something like that recently.
You can have ant seamlessly integrate with eclipse to achive that:
In Eclipse open project properties, go to "Builders", click "New...", select "Ant Builder", select a build file, go to "Targets" tab and click "Set Targets..." for "Auto Build". Select the desired target and you are done. The target will run every time you save a source file (if "Build Automatically" is selected).
Have you considered including the XML files in your jar, and loading them on startup into maps that use the enum as a key?

Are lots of inheritied single-plugin profiles in Maven a good idea?

In our infrastructure, we have lots of little Java projects built by Maven2. Each project has its own pom.xml that ultimately inherits from our one company "master" parent pom.
We've recently started adding small profiles to our parent pom, disabled by default, that, when enabled, execute a single plugin in a conventional manner.
Examples:
The 'sources' profile executes the maven-source-plugin to create the jar of project sources.
The 'clover' profile executes the maven-clover2-plugin to generate the Clover report. It also embeds our Clover license file so it need not be re-specified in child projects.
The 'fitnesse' profile executes the fitnesse-maven-plugin to run the fitnesse tests associated with the project. It contains the fitnesse server host and port and other information that need not be repeated.
This is being used to specify builds in our CI server like:
mvn test -P clover
mvn deploy site-deploy -P fitnesse,sources
and so on.
So far, this seems to provide a convenient composition of optional features.
However, are there any dangers or pitfalls in continuing on with this approach (obvious or otherwise)? Could this type of functionality be better implemented or expressed in another way?
The problem with this solution is that you may be creating a "pick and choose" model which is a bit un-mavenesque. In the case of the profiles you're describing you're sort of in-between; if each profile produces a decent result by itself you may be ok. The moment you start requiring specific combinations of profiles I think you're heading for troubles.
Individual developers will typically run into consistency issues because they forget which set of profiles should be used for a given scenario. Your mileage may vary, but we had real problems with this. Half your developers will forget the "correct" combinations after only a short time and end up wasting hours on a regular basis because they run the wrong combinations at the wrong time.
The practical problem you'll have with this is that AFAIK there's no way to have a set of "meta" profiles that activate a set of sub-profiles. If there had been a nice way to create an umbrella profile this'd be a really neat feature. Your "fitnesse" and "sources" profiles should really be private, activated by one or more meta-profiles. (You can activate a default set in settings.xml for each developer)
There isn't a problem with having multiple profiles in Maven, in fact I think they are an excellent way of allowing your build to enable and disable classes of functionality. I'd recommend naming them based on their function rather than the plugin though, and consider grouping functionally related plugins in the same profile.
As a precedent for you to follow, the Maven super POM has a "release-profile" defined, which includes configurations for the source, javadoc, and deploy plugins.
You should consider following this approach, so your "fitnesse" profile would become "integration-test", and you could choose to define additional plugins in that profile if needed at a later date. Similarly the "clover" profile could be renamed "site", and you could define additional reports in that profile, e.g. configurations for the JDepend, JXR, PMD plugins.
You seem slightly suspicious towards that approach, but you're not really sure why - after all, it is quite convenient. Anyway, that's what I feel about it: I don't really know why, but it seems somewhat odd.
Let's consider these two questions:
a) what are profiles meant for?
b) what are the alternative approaches we should should compare your approach with?
Regarding a), I think profiles are meant for different build or execution environments. You may depend on locally installed software, where you would use a profile to define the path to the executable in the respective environments. Or you may have profiles for different runtime configurations, such as "development", "test", "production".
More about this is found on http://maven.apache.org/guides/mini/guide-building-for-different-environments.html and http://maven.apache.org/guides/introduction/introduction-to-profiles.html.
As for b), ideas that come to my head:
triggering the plug-ins with command line properties. Such as mvn -Dfitnesse=true deploy. Like the well known -DdownloadSources=true for the eclipse plugin, or -Dmaven.test.skip=true for surefire.
But that would require the plugin to have a flag to trigger the execution. Not all the plug-ins you need might have that.
Calling the goals explicitly. You can call several goals on one command line, like "mvn clean package war:exploded". When fitnesse is executed automatically (using the respective profile), it means its execution is bound to a lifecycle phase. That is, whenever that phase in the lifecycle is reached, the plugin is executed.
Rather than binding plugin executions to lifecycle phases, you should be able to include the plugin, but only execute it when it is called explicitly.
So your call would look like "mvn fitnesse:run source:jar deploy".
The answer to question a) might explain the "oddness". It is just not what profiles are meant for.
Therefore, I think alternative 2 could actually be a better approach. Using profiles might become problematic when "real" profiles for different execution or build environments come into play. You would end up with a possibly confusing mixture of profiles, where profiles mean very different things (e.g. "test" would denote an environment while "fitnesse" would denote a goal).
If you would just call the goals explicitly, I think that would be very clear and flexible. Remembering the plugin/goal names should not be more difficult that remembering the profile names.

Categories

Resources