|
View:
New views
20 Messages
—
Rating Filter:
Alert me
|
| < Prev | 1 - 2 - 3 | Next > |
|
|
Re: Proper Dependency Management - HowTo?> Neither Michael nor I did propose properties for the version. Simply define
> the version in the version depMgmnt itself and you're done. No, I don't think so, my point is: parent pom: <submoulde-version> <dependency-management> [...] <version>1.2.3</version> [...] <submoulde-version> submodule: [...] <version>1.2.3</version> [...] So you will have to change it in two places (=duplicate code) where as if you are using a property, you can do it in one singular place. Peter > |
|
|
RE: Proper Dependency Management - HowTo?Hi Peter,
Peter Horlock wrote: > 2008/7/3 Jörg Schaible <Joerg.Schaible@...>: > >> Sorry, but our priority is to ensure that all artifacts are built >> with the same plugins and use the same artifact versions. In your >> model I have to duplicate all the versions for your individual >> service parents. That's what I call an anti-pattern. No, thanks, >> we've already bitten enough by that. > > > I am not sure if I properly got your point, but I also think > that using > version ranges and no proper dep. mgmt will lead to using different > submodule version in the same project. We had that with Maven 1, and > wasn't that one of the main reasons for Maven 2? The dep mgmt makes > using dep. more > strict - it allows you to exactly nail down one version all other sub > modules are sharing among each other - if, in the rare case, > that there is a > sub project that does need to violate this rule and has to > use an older / > newer version of a dep., you may do so by overiding its > version number. > > Not sure if I got it right, but imho that was Michaels point, > using version > ranges and so... Since M206 the depMgmnt will overwrite even the versions of transitive deps. If I really want to use a different version in a project, I can add either directly a version to the dependency or introduce another depMgmnt section in the POM hierarchy that overwrites the inherited version of the global master. The latter is what we do with an individual parent POM for a complete project that inherits also our global master. We originally also used only released versions but switched to SNAPSHOTs later on. However, we did not use ranges, therefore we also had to change always to a new parent after a release. With Michael's version range approach you can avoid this at least for compatible releases. IMHO you will have to find the development model that fits best your way of working. If you look at the Maven source, they use again a different approach. Therefore take your time and play with some scenarios using the different approaches. - Jörg --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@... For additional commands, e-mail: users-help@... |
|
|
RE: Proper Dependency Management - HowTo?Peter Horlock wrote:
>> Neither Michael nor I did propose properties for the version. Simply >> define the version in the version depMgmnt itself and you're done. > > > No, I don't think so, my point is: > > parent pom: > <submoulde-version> > <dependency-management> > [...] > <version>1.2.3</version> > [...] > <submoulde-version> > > submodule: > [...] > <version>1.2.3</version> > [...] > > So you will have to change it in two places (=duplicate code) where > as if you are using a property, you can do it in > one singular place. There are two different scenarios to consider: 1/ all submodules share the same development cycle and are released together: In this case the release plugin will happily adjust all the version numbers automatically. 2/ individual artifacts that are referenced with the version in the global POM: In this case I might keep the older version in the global POM while I already modify and restructure the other one without affecting all dependent artifacts immediately. Last point: The release plugin will fail to update the version of your current project if it is defined by a property. - Jörg --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@... For additional commands, e-mail: users-help@... |
|
|
Re: Proper Dependency Management - HowTo?>
> > Last point: The release plugin will fail to update the version of your > current project if it is defined by a property. > Sorry, but what's the purpose of the release plugin anyway? It's site doesn't really tell it: http://maven.apache.org/plugins/maven-release-plugin/ If I got it right, it should: 1. Create a tag of the current version of a project 2. Create a branch of the current version of a project Did I miss something? Hmm. It's not really hard to do this with subversion itself, is it??? Also, when doing it manually, isn't that better, because you got more control over what you are really doing? Same thing with "mvn deploy" - on the one hand, its nice and easy - on the other hand - isn't it TOO easy to overwrite a previously deployed version?! Don't misinterpret what I am trying to say - I don't want to argue "my way is better" or so - I just am looking for better arguments of why I should use it, I am pretty sure it has it value, I just can't (fully) see it yet. Thanks, Peter |
|
|
Re: Proper Dependency Management - HowTo?P.s.: It's really sad that there is no book / website that answers all these
kind of "best practice" answers. The upcoming mvn book "the definitive guide" is great, yet imho it's more focused on basics. :-( Peter |
|
|
Re: Proper Dependency Management - HowTo?Click on the release plugin goals from the page you linked to and the docs
describe exactly what it does... for example see: http://maven.apache.org/plugins/maven-release-plugin/examples/prepare-release.html. You'll start appreciating the release plugin when you have a multimodule project with tens of child modules in your hands and the release time comes. Kalle On Thu, Jul 3, 2008 at 8:59 AM, Peter Horlock <peter.horlock@...> wrote: > > > > > > Last point: The release plugin will fail to update the version of your > > current project if it is defined by a property. > > > > Sorry, but what's the purpose of the release plugin anyway? It's site > doesn't really tell it: > http://maven.apache.org/plugins/maven-release-plugin/ > > If I got it right, it should: > 1. Create a tag of the current version of a project > 2. Create a branch of the current version of a project > Did I miss something? > > Hmm. It's not really hard to do this with subversion itself, is it??? > Also, when doing it manually, isn't that better, because you got more > control over what you are really doing? > Same thing with "mvn deploy" - on the one hand, its nice and easy - on the > other hand - isn't it TOO easy to overwrite a > previously deployed version?! > > Don't misinterpret what I am trying to say - I don't want to argue "my way > is better" or so - I just am looking for better > arguments of why I should use it, I am pretty sure it has it value, I just > can't (fully) see it yet. > > Thanks, > > Peter > |
|
|
Re: Proper Dependency Management - HowTo?On Fri, 04 Jul 2008 02:29:07 Jörg Schaible wrote:
> > > > I can release any artifact any time... i live on the ready to release > > to production rather than beginning of build cycle line. Subtle but > > fundamental difference. And the overhead is minimal. > > The overhead is that you produce a lot of versions that may live for just a > view ours and that will not be of any use later. for you the lifecycle is 3 snapshot deploys... what if the last one breaks you code? depedending on the changeset it may be difficult to trace the path back through the changes even with source control... my way you may have extra version that are of no use unless you need to diagnose a problem with a change. Murphys law you don't need it until you do. -- Michael McCallum Enterprise Engineer mailto:gholam@... --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@... For additional commands, e-mail: users-help@... |
|
|
Re: Proper Dependency Management - HowTo?Hm, but for such analysis, isn't that what subversion is for?!
|
|
|
Re: Proper Dependency Management - HowTo?As I asked you before -
when using version ranges, how can you ensure an upcoming 2.4 dependency will not break your build that was working with 2.3 ?! Thanks, Peter |
|
|
Re: Proper Dependency Management - HowTo?On Fri, 04 Jul 2008 02:43:03 Jörg Schaible wrote:
> Sorry, but our priority is to ensure that all artifacts are built with the > same plugins and use the same artifact versions. In your model I have to > duplicate all the versions for your individual service parents. That's what > I call an anti-pattern. No, thanks, we've already bitten enough by that. I do specific plugin versions strictly and dependency versions strictly too. Its just the one is by composition and one by inheritance. Consider this thought experiment: 1) push all your configuration down to the leaf poms 2) there will be tonnes of duplication 3) now look at the patterns of duplication 4) you can use standard factoring techniques to take common sets of dependencies and put them into a composition (a pom which just collects other dependencies) (its even possible to put dependency management in here. 5) once you have factored out all the common dependencies you will see the the remaining patterns of configuration fall into functional groups... one for jars, one for wars, one for ears, one for jaxb2 projects etc etc (one could be n). So step 5 says to pull up that configuration into common parents by fucntion not by group. I guarantee that if you do this your poms will halve in size One of the _really_ important features of using composition whether or not you use depMgt is that you can (with version ranges) make a change that remains consistent across all your projects To prove this consider A extends P-1 and B extends P-2. P-2 changes the version of commons collections however C depends on A and B which version do I end up with in C? It either depends on the order of resolution of A and B OR i can add commons collections to C as well. It becomes really unwieldy. You need to factor and isolate, I'm sure it makes perfect sense. Maybe I'm missing something but I've been doing this for several years and it works. > > > All kind of "individual" plugin configuration tend to be really > "individual". As long as Maven does not support to reuse certain POM > sections (like it is now available with scope import at least for the > depMgmnt), you will not be able to avoid some duplication in the POMs. the plugin configurations are merged so you can override specific properties in the child with the 'abstract' configuration resolve from the parent hierachy > > > The overhead of putting things in the company pom is that you need to > > change all the projects to the new version OR you can use snapshots > > and make it a major overhead to start a release cycle > > It depends on your development model. We do the second and it works well. it does and thats fair enough. But I worked on another project where they did the same thing and said it worked well. But people still wasted half days all the time when someone snapshot'd something that broke everything else accidentally and there was no simple path backward. You might as well go back to one big source tree... Please take all comments with a large grain of salt. Not intending to offend anyone, ;-) -- Michael McCallum Enterprise Engineer mailto:gholam@... --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@... For additional commands, e-mail: users-help@... |
|
|
Re: Proper Dependency Management - HowTo?On Fri, 04 Jul 2008 02:52:09 Peter Horlock wrote:
> The problem I see with version ranges, is you start loosing control. Not true it means you have complete control. Unless you use [1.5] in all your versions you are asking maven to make a best effort to give you 1.5. > I guess the vital part to make the use of version ranges work (at all) is > that every developer has to follow the rule No version ranges work fine in most cases, however I find that its best to keep it simple. You only and always change the minor version when you release an artifact unless you have branched and then you increment the patch number. The major version is a discussion with the team to say we are adding this new feature and need to make this change that will break the previous contract of the artifact. > > major.minor.patch... > > So far, we have been very loose with versions - Someone changes 5 lines in > the code, makes a new (patch) version, someone else changes another 7 > lines, makes another (patch) version, and so on - we keep on "patching" the > jar - 1.3.57 - I wonder when we will hit a hundred or a thousand! ;-) versions have nothing to do with how much or how little has changed. It usually depends on the artifact. Some are volatile and other not. The non volatile ones tend to get reused all over the place. the only time we have had broken builds was when someone made a change that broke the contract and had not discussed it. its easy enough to adjust a range if you have to e.g. [2,2.4-!) I think i might be possible to > > So I guess if EVERY developer would only use the "patch section" if it was > really just a minor patch that will not influence anything really, but > would use the minor or major section for all other changes, ranges might > work without breaking other ppls builds - but this mechanismus counts on > this very ability, which is hard to maintain, especially with new > developers joining the team. When you have strict versions everyone has to > change to a new version deliberately. I specifically set things up this was to cope with new developers, they can pick up one artifact it just works, they can build ti and release it. You can get them started and ease them into how things work. > > About the thing with version numbers as property values in the parent pom - > I am still not sure this is the best way, especially not with project that > are not really shared by others, Its a bad idea all around. it makes maintenance and nightmare and plugins and other things don't always interpolate those properties correctly, and you end up with the version being that of some obscure plugin... very annoying. > but this is the easiest way to update the dependency management section - > otherwise, when someone changes the version of a submodule, one has to > change this version, as well as the version in dep. mgmt. see previous post on sticking depMg in another common project with a pom dependency ... i dont do it this way but use a similar approach with factored dependencies > > Hmmmm, this is really hard to swallow, I can't really find THE one and only > solution of how to solve this dilemma - well, maybe I am still missing > something? -- Michael McCallum Enterprise Engineer mailto:gholam@... --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@... For additional commands, e-mail: users-help@... |
|
|
Re: Proper Dependency Management - HowTo?On Fri, 04 Jul 2008 02:59:10 Peter Horlock wrote:
> 2008/7/3 Jörg Schaible <Joerg.Schaible@...>: > > Sorry, but our priority is to ensure that all artifacts are built with > > the same plugins and use the same artifact versions. In your model I have > > to duplicate all the versions for your individual service parents. That's > > what I call an anti-pattern. No, thanks, we've already bitten enough by > > that. > > I am not sure if I properly got your point, but I also think that using > version ranges and no proper dep. mgmt will lead to using different > submodule version in the same project. We had that with Maven 1, and wasn't manageable. with the composition of depMgt with the new pom import support you can do what i'm saying with depMagt and not using inheritance -- Michael McCallum Enterprise Engineer mailto:gholam@... --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@... For additional commands, e-mail: users-help@... |
|
|
Re: Proper Dependency Management - HowTo?On Fri, 04 Jul 2008 03:59:29 Peter Horlock wrote:
> Sorry, but what's the purpose of the release plugin anyway? It's site > doesn't really tell it: > http://maven.apache.org/plugins/maven-release-plugin/ Very good question and simple to answer... release-prepare - the release plugin will build and test your project then tag it. release-perform -check out the code from the tag and build the artifact and test it and then deploy it essentially a maven repository is just a cache of prebuilt tags, you can always rebuild an artifact by providing the tag path to release-perform once you are in the habit of releasing and set up some aliases or batch files its painless, -- Michael McCallum Enterprise Engineer mailto:gholam@... --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@... For additional commands, e-mail: users-help@... |
|
|
Re: Proper Dependency Management - HowTo?On Fri, 04 Jul 2008 10:01:43 Peter Horlock wrote:
> Hm, but for such analysis, isn't that what subversion is for?! sure but where to look, if you built a snapshot what revision am i looking for. If you have tags then you can easily see changes between checkpoints -- Michael McCallum Enterprise Engineer mailto:gholam@... --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@... For additional commands, e-mail: users-help@... |
|
|
Re: Proper Dependency Management - HowTo?On Fri, 04 Jul 2008 10:08:44 Peter Horlock wrote:
> As I asked you before - > > when using version ranges, how can you ensure an upcoming 2.4 dependency > will not break your build that was working with 2.3 ?! there are a few ways.... but mostly its development process 0) communication 0) planning 1) run an CI server that runs cycles of every trunk and against every trunk 2) use the reactor to run all the tests before you release 2.4 3) make when the distance between projects is not too large you should problably be using refactoring tools to make changes that break apis and it will apply to the depedent project too 4) use a staging repository for CI before promotion to the release repository There is another factor to consider though... "breaking" is only significant if its difficult to fix... with version ranges it is easy to remove the bad version from the resolution tree for all projects that may be affected and then beer fine those responsible ;-) there will never be a tool that stops developers making mistakes, there are tools to help developers mitigate the cost of those mistakes, thank you maven. -- Michael McCallum Enterprise Engineer mailto:gholam@... --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@... For additional commands, e-mail: users-help@... |
|
|
Re: Proper Dependency Management - HowTo?Okay,
one last thing - this conversation has helped me a LOT already, but, to catch it all, I need some more: 1) You say your version ranges wouldn't break a build - but what about transitive dependencies that these new versions might have (in case they are overwriting depd. mgmt for example)? What about new 3rd party dependencys, what if they have new third party dependencies? When I moved our project from maven to maven 2, with the transitive dependencies the jars /wars of the sub projects each got some new jars, that were not included before, and this sometimes made the project fail at runtime - sometimes even in the most obscure and hidden places, hard to find - same thing could happen with new dependency versions, couldn't it? I am therefore not yet totally convinced of transitive dependencies - it hides things, and then when you don't expect it, it might fail in a productive environment, if a test didn't catch it before. 2) When you are talking about composition, I know finally understood you are talking about using poms as a container to combine dependencies. But how soon will you start making such a combine pom? If you got 2 similar jars? 10? 20? What's the best ratio from your expierence? 3) Will those "composition poms" not clutter your project structure even more? With maven 1 you had one pom to maintain and to understand - now with maven 2 you already got 2. Now when using "composition poms", you will end up with 3,4,5....10 Poms just got one single project... ??! Our developers are already grumping about having to maintain the parent pom AND their project pom - I mean it has all its nice vantages, but on the other hand, it increases the projects complexity, in some way, too, you have to admit, don't you?! 4) I don't yet completly get the vantage of having all those seperate jars in a single project, instead of one hugh block of code - I mean, yes, when someone breaks something in "his own code region", the others may still work on their code without it influencing them - but what about runtime errors - when you are using separate jars its all nice and divided, but this somehow may only delay the error from happening in another remote code region. I mean, imagine everyone is happily working with dependency 1.2.3, now someone releases 1.2.4. To find an obscure bug, it often needs a certain time for ppl to find it, and when everyone is still working with 1.2.3, noone will actually find this error until finally they will change to 1.2.4. I mean, when no separate jars are used, this might sometimes cause the entire project to break - but doesn't that also drastically show everyone that this class / this external jar has influences on all sorts of other code regions? Compare it with teams that are closely working together - the more closer, the more often they might quarrel over something - but as soon as this dispute is resolved, afterwards they will have grown an even better community - where's with closed doors, when they don't see or talk to each other, they won't have problems in the short run, but when they finally meet and talk about things it might bang much stronger.... Do you get my point? It's hard to explain, I hope you get my analogy. A colleague pointed this out to me, and I didn't know how to answer it - imho it is a valid argument, isn't it??? Last but not least - we have about 10 sub projects, but in one of those sub projects, there are between 1-4 people working. So you still got the problem if you break something in a sub project, you will influence up to 3 other developers.... Please, bring some light in my confusion! :-) Thanks, Peter |
|
|
RE: Proper Dependency Management - HowTo?Hi Peter,
Peter Horlock wrote: > Okay, > > one last thing - this conversation has helped me a LOT > already, but, to > catch it all, I need some more: > > 1) You say your version ranges wouldn't break a build - but what about > transitive dependencies that these new versions might have (in case > they are overwriting depd. mgmt for example)? What about new 3rd > party dependencys, what if they have new third party dependencies? > When I moved > our project > from maven to maven 2, with the transitive dependencies the > jars /wars of > the sub projects each got some new jars, that were not > included before, and > this sometimes made the project fail at runtime - sometimes > even in the most > obscure and hidden places, hard to find - same thing could > happen with new > dependency versions, couldn't it? I am therefore not yet > totally convinced > of transitive dependencies - it hides things, and then when > you don't expect > it, it might fail in a productive environment, if a test > didn't catch it > before. That's Michael's point 8. If you upgrade a 3rd party dep, you should really have a look at the dependency tree to see, what has changed. > 2) When you are talking about composition, I know finally > understood you are > talking about using poms as a container to combine > dependencies. But how > soon will you start making such a combine pom? If you got 2 > similar jars? > 10? 20? What's the best ratio from your expierence? It depends on your use case how you use a dependency normally. Michael's example was Hibernate. It's more or less always if you recognize that you have to add the same dependencies (and exclusions) in several places only because you like to use framework X in a special way. Checkout also the scope import introduced with M209. > 3) Will those "composition poms" not clutter your project > structure even > more? > With maven 1 you had one pom to maintain and to understand - > now with maven > 2 you already got 2. Now when using "composition poms", you > will end up with > 3,4,5....10 Poms just got one single project... ??! Our developers are > already grumping about having to maintain the parent pom AND > their project > pom - I mean it has all its nice vantages, but on the other hand, it > increases the projects complexity, in some way, too, you have > to admit, > don't you?! Managing dependencies *is* complex. Managing them in M1 was worse. Synchronizing a dozen of your projects to use the dependencies in the same versions was horrible (even with entities). The composition poms allow you to have specialists for a framework, who define what is really needed, while all the others simply use the composition pom and can expect that it works. > 4) I don't yet completly get the vantage of having all those > seperate jars > in a single project, instead of one hugh block of code - I > mean, yes, when > someone breaks something in "his own code region", the others > may still work > on their code without it influencing them - but what about > runtime errors - > when you are using separate jars its all nice and divided, > but this somehow > may only delay the error from happening in another remote > code region. I > mean, imagine > everyone is happily working with dependency 1.2.3, now > someone releases > 1.2.4. To find an obscure bug, it often needs a certain time > for ppl to find > it, and > when everyone is still working with 1.2.3, noone will > actually find this > error until finally they will change to 1.2.4. I mean, when > no separate jars > are used, this might sometimes cause the entire project to break - but > doesn't that also drastically show everyone that this class / > this external > jar has influences on all sorts of other code regions? > Compare it with teams > that are closely working together - the more closer, the more > often they > might quarrel over something - but as soon as this dispute is > resolved, afterwards they will have grown an even better community - > where's with > closed doors, when they don't see or talk to each other, they > won't have > problems in the short run, but when they finally meet and > talk about things > it might bang much stronger.... > Do you get my point? It's hard to explain, I hope you get my > analogy. A > colleague pointed this out to me, and I didn't know how to > answer it - imho > it is a valid argument, isn't it??? That's what Michael solves declaring the ranges and we by using SNAPSHOTs. However, it is no automatism for detecting runtime incompatibilities. So write your unit and integration tests ;-) > Last but not least - we have about 10 sub projects, but in > one of those sub > projects, there are between 1-4 people working. So you still > got the problem > if you break something in a sub project, you will influence > up to 3 other > developers.... It's policy. While sub project 3 is working with the latest stuff of sub project 1, sub project 5 might decide not to switch and wait for a stable release and do their integration then. Maven simply helps you to support both scenarios. > Please, bring some light in my confusion! :-) Hope this helps :) - Jörg --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@... For additional commands, e-mail: users-help@... |
|
|
Re: Proper Dependency Management - HowTo?Michael McCallum <gholam@...> wrote on 03/07/2008 14:05:09:
> 11) don't mix inheritance and aggregation. that means a parent pom NEVER ever > has modules, if you think about the concept for a minute - or longer - there > will be a moment of enlightenment Sorry for jumping in here, but wehy not? The only time (admitedely) I use this is for a multi module J2EE project, where each module (WAR, EAR, EJB, JAR etc) all have the multi module pom as their parent, and the multi module pom has the corporate one as it's parent. I was told to do this, and in fact, if you you use archetype:create-from-project (?) that is how it generates the pom structure of the generated archetype. So, I'm curious as to why you would say not to do this. -Chris ********************************************************************** CAUTION - This message is intended for the addressee named above. It may contain privileged or confidential information. If you are not the intended recipient of this message you must: - Not use, copy, distribute or disclose it to anyone other than the addressee; - Notify the sender via return email; and - Delete the message (and any related attachments) from your computer immediately. Internet emails are not necessarily secure. Australian Associated Motors Insurers Limited ABN 92 004 791 744 (AAMI), and its related entities, do not accept responsibility for changes made to this message after it was sent. Unless otherwise stated, views expressed within this email are the author's own and do not represent those of AAMI. ********************************************************************** --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@... For additional commands, e-mail: users-help@... |
|
|
Re: Proper Dependency Management - HowTo?> 11) don't mix inheritance and aggregation. that means a parent pom NEVER
ever > has modules, if you think about the concept for a minute - or longer - there > will be a moment of enlightenment > > > structure of the generated archetype. > > So, I'm curious as to why you would say not to do this. > Yeah, me too! First, I had a parent pom, and a "all-projects-pom" which was just and only a multimodule pom. But then you had even one more pom, and we decided to put the multimodule stuff right into the parent pom. using the "-N" flag allows to simply work (package, install, deploy, site...) with the parent pom, while without you may easily work(package, install, deploy, site...) on all projects at once. Thanks, Peter |
|
|
Re: Proper Dependency Management - HowTo?Michael McCallum wrote:
> On Fri, 04 Jul 2008 03:59:29 Peter Horlock wrote: >> Sorry, but what's the purpose of the release plugin anyway? It's site >> doesn't really tell it: >> http://maven.apache.org/plugins/maven-release-plugin/ > Very good question and simple to answer... > > release-prepare - the release plugin will build and test your project then > tag it. One important point not mentioned: It *ensures* that you have *no* local changes. :) > release-perform -check out the code from the tag and build the artifact > and test it and then deploy it > > > essentially a maven repository is just a cache of prebuilt tags, you can > always rebuild an artifact by providing the tag path to release-perform > > > once you are in the habit of releasing and set up some aliases or batch > files its painless, --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@... For additional commands, e-mail: users-help@... |
| < Prev | 1 - 2 - 3 | Next > |
| Free embeddable forum powered by Nabble | Forum Help |